|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
默认情况下,在32位cpu里,gcc对于结构体的对齐方式是按照四个字节来对齐的。看以下结构体 , _! v5 K q+ I3 P7 R
typedef struct pack{
+ ^& L; u: }! N) ?( l0 P* n char a;
! k8 K# Q% y* l9 s4 s; V& q( N int b; ; F2 g6 @) `$ ]4 O V' g2 x) V
short c; 5 r; F4 o$ V9 a; n; o
}pack;
5 q+ U% i( ]( \! [3 O/ B+ y 对于Pack结构体,默认情况下在ARM/386平台下(别的平台没试过)sizeof(pack)=12,求解过程如下: * q7 y, S) B2 d1 \: F
sizeof(char)=1; ! X9 ]# j6 h5 }& p6 ?
下一个int b,由于是四个字节,要求b的开始地址从32的整数倍开始,故需要在a后面填充3个没用的字节,记为dump(3),sizeof(b)=4,此时相当于结构体扩充为 H( _% [ V$ ~; p3 j; r$ v
char a;
" [6 |8 r3 B% ?* T/ N9 _ char dump(3); 1 ?& B, }$ J, q+ X8 y
int b;
9 F) `: G E5 c3 K% Y, I5 h5 } 看short c,现在c的前面有8个字节,c是两个字节,c的开始地址是从16的整数开始,在b前面不需再加东西.此时对于结构体来说,sizeof(pack)=10,但是这不是最终结果,最后总的字节数也要能被4个字节整除,所以还需在short c后面再加 ! [. H6 f# ?# }8 A# r( T
dump(2);
5 g' C8 x( j) q& o% a 故总的字节数为12. 3 J1 O* [5 Y8 s" R+ z
当然以上说的只是简单的情况,下面谈谈arm,x86在gcc里关于内存边界字节对齐的区别.对于同样的结构体,在386下 4 e# b; Z/ _: W* s; T5 O& t
#prama pack(1)
! ~) Y& ?/ W! `6 k0 x 后,sizeof(pack)=1 4 2=7 " c9 L4 b" C5 H$ @; H5 b
而在arm下同样的操作sizeof(pack)=1 4 2 1=8,即虽然b根a之间不要填充但总的长度必须要是4的整数倍.
6 I) ~9 Y$ X: H& Q3 b9 [& s% o1 h 在arm 下要使结构体按指定字节对齐,可行的方法
) C6 E* u& c5 x1 f+ w 1.在makefile里加-fpack-struct 选项,这样的话对所有的结构按一字节对齐.
K# Q% N6 H8 c: [ 不得不说,确实有那么些质量较差的程序可能需要你部分自然对齐,部分一字 节对齐,此时 5 I* `/ o- p Q) z q# a% K
2. typedef struct pack{
* f5 C4 X1 v& \6 J% f! r* @ }__attribute__((packed))
- @* S' d1 c7 E1 P2 U# j! F! j; H1 c 可利用__attribute__属性
! G9 [; T7 ^8 i; Z2 v0 n: `+ o8 y! O 当然最后的方式,还是自己去看arm体系结构与gcc编译选项了。
% A# c3 M& |4 I+ N+ e$ i |
|