|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
默认情况下,在32位cpu里,gcc对于结构体的对齐方式是按照四个字节来对齐的。看以下结构体 # R: [; @- B% j4 q; F
typedef struct pack{
5 x8 \0 }5 p) N; ~/ ~- x char a; - k" ], n Z1 s% `
int b; % j0 V1 S `- R8 D& f
short c;
+ H0 T @6 e3 i }pack; " j I G- u$ o9 h" ^5 r% `
对于Pack结构体,默认情况下在ARM/386平台下(别的平台没试过)sizeof(pack)=12,求解过程如下: ( R2 d" O1 D; ?1 d5 j1 A* W
sizeof(char)=1; % x: R- X% M4 m+ g q) E
下一个int b,由于是四个字节,要求b的开始地址从32的整数倍开始,故需要在a后面填充3个没用的字节,记为dump(3),sizeof(b)=4,此时相当于结构体扩充为
$ e+ F( S6 G: c1 V3 W, g5 l char a;
. A9 m e! Y- W7 O char dump(3); " V" L- u* @+ t2 L# K4 b6 ^: A
int b;
1 \+ I( }$ L3 a9 p: } 看short c,现在c的前面有8个字节,c是两个字节,c的开始地址是从16的整数开始,在b前面不需再加东西.此时对于结构体来说,sizeof(pack)=10,但是这不是最终结果,最后总的字节数也要能被4个字节整除,所以还需在short c后面再加 8 }& @1 e) {/ }
dump(2);
2 V# S* k' ~" G8 h 故总的字节数为12. # k# W$ k E/ G' f
当然以上说的只是简单的情况,下面谈谈arm,x86在gcc里关于内存边界字节对齐的区别.对于同样的结构体,在386下
) ]2 [: s/ \6 E% f6 h3 M# @1 |0 n #prama pack(1)
7 W* i3 X F* u- n" X1 w 后,sizeof(pack)=1 4 2=7 L) E# l& j. M0 c
而在arm下同样的操作sizeof(pack)=1 4 2 1=8,即虽然b根a之间不要填充但总的长度必须要是4的整数倍.
! \4 x D* O1 D K/ c6 k) u2 j 在arm 下要使结构体按指定字节对齐,可行的方法
9 F; g) y* @3 X" q2 L, T+ J8 B 1.在makefile里加-fpack-struct 选项,这样的话对所有的结构按一字节对齐. + ?8 [& z; Q3 D
不得不说,确实有那么些质量较差的程序可能需要你部分自然对齐,部分一字 节对齐,此时 / Q" x! e! W2 k* l+ K
2. typedef struct pack{ + ]- ]$ K- r0 d
}__attribute__((packed))
1 I9 m' f( R; n" x3 W5 |1 n 可利用__attribute__属性 2 ` E7 \4 s1 M. G6 h; X- o% k( a
当然最后的方式,还是自己去看arm体系结构与gcc编译选项了。: N& G7 s( ~. D3 d8 Q* E5 a8 P
|
|