|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
默认情况下,在32位cpu里,gcc对于结构体的对齐方式是按照四个字节来对齐的。看以下结构体
0 {* y0 S! x9 B+ r+ a typedef struct pack{ 1 G1 C+ @- D$ h
char a; ( {. L/ h" }- y' W; m
int b; ! I& r* V/ H5 c6 L% Q; h7 s
short c;
6 c, \! ^# l3 Q; r) a0 D2 t3 u' Y }pack; % d% c8 i; M8 B; Z4 S3 g
对于Pack结构体,默认情况下在ARM/386平台下(别的平台没试过)sizeof(pack)=12,求解过程如下: # Q0 S1 T& h& w
sizeof(char)=1;
- v' c% q0 l6 ?& p( G 下一个int b,由于是四个字节,要求b的开始地址从32的整数倍开始,故需要在a后面填充3个没用的字节,记为dump(3),sizeof(b)=4,此时相当于结构体扩充为
/ R( ?( ]" B4 w$ I0 Y. g, K char a; ' o c( c7 N5 A0 T( v8 {, u+ U0 U
char dump(3); & J3 w# I: r% q4 F/ W# B
int b; $ ?# A9 L, s& Z$ W8 A
看short c,现在c的前面有8个字节,c是两个字节,c的开始地址是从16的整数开始,在b前面不需再加东西.此时对于结构体来说,sizeof(pack)=10,但是这不是最终结果,最后总的字节数也要能被4个字节整除,所以还需在short c后面再加
1 W4 h: }7 q" G% x3 j w# f dump(2); ( ]# c+ l: d' X/ g x# ~
故总的字节数为12.
2 q$ H6 J# V" f* [* l 当然以上说的只是简单的情况,下面谈谈arm,x86在gcc里关于内存边界字节对齐的区别.对于同样的结构体,在386下
0 C3 d! k) i& x: w& _. P #prama pack(1)
1 |2 A% ~( ~. d, ^ R% [; f 后,sizeof(pack)=1 4 2=7 1 `2 L2 R7 c% j
而在arm下同样的操作sizeof(pack)=1 4 2 1=8,即虽然b根a之间不要填充但总的长度必须要是4的整数倍. . c1 [! M" Q; _: d1 \& X
在arm 下要使结构体按指定字节对齐,可行的方法
4 G- N) ^. K5 T" ^ 1.在makefile里加-fpack-struct 选项,这样的话对所有的结构按一字节对齐.
" `: I$ {8 _8 r# B" G 不得不说,确实有那么些质量较差的程序可能需要你部分自然对齐,部分一字 节对齐,此时
2 K9 n% `' `1 }: z) b/ C/ b 2. typedef struct pack{ ( F* s# v7 A# X! X9 N! v
}__attribute__((packed))
& x, T9 ?9 i- q! h! B- } 可利用__attribute__属性 m; \. }0 ^; ~7 o; B
当然最后的方式,还是自己去看arm体系结构与gcc编译选项了。
0 p, X+ D1 \* v/ `' X5 @ |
|