免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: cellar
打印 上一主题 下一主题

关于字符对齐一问,牛人看过来 [复制链接]

论坛徽章:
2
亥猪
日期:2014-03-19 16:36:35午马
日期:2014-11-23 23:48:46
11 [报告]
发表于 2006-11-30 14:03 |只看该作者
可以阿, 难道你的机器上 uchar[10]的数组 for 一遍会出错吗?
早期的arm ldr和str 只能够直接访问 8bit和32bit ,后来的比较新的arm加入了16bit的访问方式。
早期arm需要处理16bit时,是由编译器帮你做位变换,因此虽然功能正确但是效率十分低下。现在的,比如我手上的arm9,对8/16/32的访问都是很直接的。不过寄存器是32位,8/16最后编译器都必须帮你扩展成32,才能放入寄存器,这个问题仍然存在。

论坛徽章:
0
12 [报告]
发表于 2006-11-30 14:07 |只看该作者
原帖由 yg 于 2006-11-30 13:48 发表
32位系统,缺省情况下都是4字节对齐的。
变量是不会扩展的,但下一个非char型变量会从余4为0的地址开始。


以下为arm9下实测:

  1. //...
  2. #pragma pack (1)
  3. struct xxx{
  4. char a;
  5. long b;
  6. short c;
  7. };
  8. int main(){
  9. struct xxx x;
  10. printf("&a=%p\n&b=%p\n",&x.a,&x.b);
  11. }
复制代码


定义后打印出的结果
&a=0xbffffe8c
&b=0xbffffe8d

论坛徽章:
0
13 [报告]
发表于 2006-11-30 14:11 |只看该作者
原帖由 gvim 于 2006-11-30 14:03 发表
可以阿, 难道你的机器上 uchar[10]的数组 for 一遍会出错吗?
早期的arm ldr和str 只能够直接访问 8bit和32bit ,后来的比较新的arm加入了16bit的访问方式。
早期arm需要处理16bit时,是由编译器帮你做位变换, ...


这位老大出现了,结论是让人信服的。

以上的程序中有:

  1. struct xxx{
  2. char a;
  3. long b;
  4. short c;
  5. };
复制代码

x86下sizeof(struct xxx); =>7,arm9下sizeof(struct xxx) =>8
是因为arm下的struct空间必须是4的倍数吗?还是因为其它?谢谢


btw:能加我msn吗

[ 本帖最后由 cellar 于 2006-11-30 14:12 编辑 ]

论坛徽章:
0
14 [报告]
发表于 2006-11-30 14:20 |只看该作者
#pragma pack (1)

当然不会做4字节对齐了

论坛徽章:
0
15 [报告]
发表于 2006-11-30 14:22 |只看该作者
原帖由 yg 于 2006-11-30 14:20 发表
#pragma pack (1)

当然不会做4字节对齐了


不加也不是,兄弟,自己试试

论坛徽章:
0
16 [报告]
发表于 2006-11-30 14:25 |只看该作者
原帖由 mynets 于 2006-11-30 14:16 发表
哎,设计网络协议的牛人们早考虑到这些了,看看这个ip头,都是32位对齐了的,不用pack了。
访问奇地址的问题,是cpu如何从总线上取数据的问题了,跟程序没什么关系,它可能会一次取整个32位,然后把你需要的8位分 ...


嗯,读内核代码就象读好文学,每读一遍就会有新收获,不到一定的程度就领会不了那个程度的东西啊...

论坛徽章:
0
17 [报告]
发表于 2006-11-30 14:33 |只看该作者
你试过吗?
linux:
&a=0xbfeff3f0
&b=0xbfeff3f4
aix:
&a=2ff22950
&b=2ff22954
sco:
&a=7ffffa24
&b=7ffffa28
没看出有什么特别的

论坛徽章:
0
18 [报告]
发表于 2006-11-30 14:45 |只看该作者
原帖由 yg 于 2006-11-30 14:33 发表
你试过吗?
linux:
&a=0xbfeff3f0
&b=0xbfeff3f4
aix:
&a=2ff22950
&b=2ff22954
sco:
&a=7ffffa24
&b=7ffffa28
没看出有什么特别的




  1. struct xxx{
  2. char a;
  3. long b;
  4. short c;
  5. };
复制代码

是这个结构??

怎么和我的结果差好多....

论坛徽章:
0
19 [报告]
发表于 2006-11-30 14:49 |只看该作者
用你的程序直接粘贴的
cc -oa a.c
不要加特殊的编译参数

论坛徽章:
2
亥猪
日期:2014-03-19 16:36:35午马
日期:2014-11-23 23:48:46
20 [报告]
发表于 2006-11-30 15:09 |只看该作者
"老大"这个帽子还是不怎么适合我,呵

我个人认为 对齐需要分两种,一种是处理器的对齐,一种是编译器的对齐。
处理器对齐 在arm上意味着byte必须以8bit对齐,int32必须以32bit对齐。而在x86上,由于CISC处理器特性,它支持十分复杂的存储器操作,这一点从支持的多达10多种 寻址方式上就可以体会出来。因此x86上即使int32也可以按照8bit对齐,只不过损失的是访问效率。
编译器对齐 意味着编译器选择自己喜欢的方式来完成多起操作。如果不能处理器对齐,那么编译器会选择自己喜欢的方式处理。

以arm为例:
下面是你的简短代码

  1. #pragma pack(1)
  2. struct xxx {
  3.     char a;
  4.     long b;
  5.     short c;
  6. };

  7. int
  8. main()
  9. {
  10.     struct xxx m;
  11.     m.a = 'a';
  12.     m.b = 12;
  13.     m.c = 23;
  14.     return sizeof(struct xxx);
  15. }
复制代码

首先看默认的平台,编译器如何处理
vi[~]# arm--netbsdelf-gcc -S mmm.c -o mmm.S
    mov r3, #97
    strb    r3, [fp, #-19]
    mov r3, #0
    orr r3, r3, #12
    strb    r3, [fp, #-18]
    mov r3, #0
    strb    r3, [fp, #-17]
    mov r3, #0
    strb    r3, [fp, #-16]
    mov r3, #0
    strb    r3, [fp, #-15]
    mov r3, #0
    orr r3, r3, #23
    strb    r3, [fp, #-14]
    mov r3, #0
    strb    r3, [fp, #-13]
    mov r3, #7
    mov r0, r3

这里十分明显,这里不能够依赖处理器对齐,因此编译器完全把所有元素都按照strb来处理,效率低下不是一般。但是,sizeof的结果,是7。
将编译参数增加为: arm--netbsdelf-gcc -march=armv4 -S mmm.c -o mmm.S
你可以自己看一下,编译器仍然将所有元素按照strb处理。

如果去掉#pragma pack(1)
仍然使用默认选项编译,结果是
    mov r3, #97
    strb    r3, [fp, #-24]
    mov r3, #12
    str r3, [fp, #-20]
    mov r3, #23
    mov r2, #0
    strb    r3, [fp, #-16]
    strb    r2, [fp, #-15]
    mov r3, #12
    mov r0, r3

当然,sizeof是12,但是最后的short不支持直接操作,编译器帮你换成strb操作。

添加-mach=armv4
    mov r3, #97
    strb    r3, [fp, #-24]
    mov r3, #12
    str r3, [fp, #-20]
    mov r3, #23
    strh    r3, [fp, #-16]  @ movhi
    mov r3, #12
    mov r0, r3

呵呵,新平台,当然就有strh了。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP