|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
默认情况下,在32位cpu里,gcc对于结构体的对齐方式是按照四个字节来对齐的。看以下结构体
' V5 T; s5 c I. Z8 |4 [
3 E" T( o5 S( V# z) d
" R( g+ ]+ O, I; e0 g O6 H6 }" y* ? typedef struct pack{1 G- s" ?, n+ q5 R, d
: ]' |/ c3 h, s5 u7 Y6 H char a;
3 A0 K u2 O6 z) e. r
: t6 P7 J# I8 H" W3 z- k: F! x- ~ int b;* A7 K" j/ M& h, U. t, J
K' w G- o. F3 t1 H# M short c;
1 h8 \; b* J' R; @3 t( S0 Y0 U: Z9 l# n0 a8 K
}pack;
3 r4 F! y2 H; O: r/ F D9 T a M7 ]; {6 v. d
对于Pack结构体,默认情况下在arm/386平台下(别的平台没试过)sizeof(pack)=12,求解过程如下:# }3 n O+ h( F2 v% j% r: y
' i. Z, }! v4 H5 o- ^ sizeof(char)=1;: S& h5 N6 P. A& Y( }' g
3 X# M9 K0 r2 H 下一个int b,由于是四个字节,要求b的开始地址从32的整数倍开始,故需要在a后面填充3个没用的字节,记为dump(3),sizeof(b)=4,此时相当于结构体扩充为
1 H5 a: O; K: \" N: X( U
8 l5 N3 f3 z1 [% B" f char a;9 t- X% d' [* O& V/ @& u7 o8 I
6 n+ T# N& `+ Y$ J
char dump(3);2 Z- m$ ]! ?7 L
. H/ b Y3 F$ |: u: I8 W0 Y; { int b;/ v. J1 w, }" T" |! O( G
+ g1 {8 ^% }5 t9 v$ y9 x: q5 | 看short c,现在c的前面有8个字节,c是两个字节,c的开始地址是从16的整数开始,在b前面不需再加东西.此时对于结构体来说,sizeof(pack)=10,但是这不是最终结果,最后总的字节数也要能被4个字节整除,所以还需在short c后面再加6 @$ @- t- [+ K' O
. L) @$ e) B( K+ e! R v
dump(2);
1 {% n8 E3 ~ A+ ^# z, @$ p6 P5 g: Y7 M2 o
故总的字节数为12.+ f2 P z& \5 v9 o
) l7 ?- e1 y: Q3 T. H& l 当然以上说的只是简单的情况,下面谈谈arm,x86在gcc里关于内存边界字节对齐的区别.对于同样的结构体,在386下
' g3 Y+ B/ F3 z" v2 p& }
: _3 H7 M1 r# ~+ w7 t4 @ #prama pack(1)
* R/ y0 t! N% H- z1 t7 Z. a, b& U1 F6 Y" L- r" `
后,sizeof(pack)=1 4 2=7
% p% T5 [: D/ x8 d! Y" t. P5 m& Q) Y) c' [
而在arm下同样的操作sizeof(pack)=1 4 2 1=8,即虽然b根a之间不要填充但总的长度必须要是4的整数倍.
; {6 \. B' n( ^$ S& [( D% f+ B3 a8 w& S9 _
在arm 下要使结构体按指定字节对齐,可行的方法
% Q$ R& W7 M) {- b5 t- c8 B6 j$ `$ Y s5 x9 {' u; o, D% Q
1.在makefile里加-fpack-struct 选项,这样的话对所有的结构按一字节对齐.! U4 |; ] [% [; u0 A. n5 c; G9 n# Y# P
1 P% ~2 @9 L8 h2 w$ T
不得不说,确实有那么些质量较差的程序可能需要你部分自然对齐,部分一字 节对齐,此时# _" U# W! y0 a2 r F
, N! _2 p" r5 A8 O; }: w: D( {2 ]
2. typedef struct pack{
& c ]* b1 s. ~
& Q e) O% U+ e/ p0 s1 v: B3 ? }__attribute__((packed))
. n- ^% P7 k- v! r7 @" B2 z% b
$ `" d M* q, U m# l2 J 可利用__attribute__属性
7 X% S A. Z1 O% Y/ q$ z# J% z9 O4 ~) M3 S' Y" e! ]
当然最后的方式,还是自己去看arm体系结构与gcc编译选项了。
9 p( G- `, m! Q; `# ^$ h+ J2 X& X( p5 b
|
|