|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
默认情况下,在32位cpu里,gcc对于结构体的对齐方式是按照四个字节来对齐的。看以下结构体
* n' }8 h0 B$ m0 g, p% }. {5 j typedef struct pack{ $ `% t% N, X2 \# d1 e7 A
char a; 9 i3 V. j, m% {1 r# Q! A7 V/ n
int b; ! L4 {& t/ v) U+ Z; v
short c; ! i3 E" c4 K3 ]$ w7 K
}pack;
4 K' M4 ~. s4 |; l, `' A; v 对于Pack结构体,默认情况下在ARM/386平台下(别的平台没试过)sizeof(pack)=12,求解过程如下:
" D4 q) q: K2 m- N% x' V& ]0 S- H0 M sizeof(char)=1; 9 h, n2 G& u5 W* m
下一个int b,由于是四个字节,要求b的开始地址从32的整数倍开始,故需要在a后面填充3个没用的字节,记为dump(3),sizeof(b)=4,此时相当于结构体扩充为 9 n5 F& k, I4 N3 B
char a;
! Z2 U: T; U( ~! Q4 y char dump(3);
' b/ H8 u* H0 z6 C int b;
& T1 {- P [' \" ` 看short c,现在c的前面有8个字节,c是两个字节,c的开始地址是从16的整数开始,在b前面不需再加东西.此时对于结构体来说,sizeof(pack)=10,但是这不是最终结果,最后总的字节数也要能被4个字节整除,所以还需在short c后面再加 . A2 t, Z4 u7 V3 T3 Y: ]
dump(2);
! h" e# p* a7 R: Y: l# F! k& d g 故总的字节数为12.
7 Y3 I' y2 f2 R0 m 当然以上说的只是简单的情况,下面谈谈arm,x86在gcc里关于内存边界字节对齐的区别.对于同样的结构体,在386下
8 v/ Y$ a! c$ Z1 e( F# T+ V# n3 ] #prama pack(1)
, i1 m% q1 D# w" v 后,sizeof(pack)=1 4 2=7
1 w. U" i: D% O h$ H ?) s: M1 t 而在arm下同样的操作sizeof(pack)=1 4 2 1=8,即虽然b根a之间不要填充但总的长度必须要是4的整数倍.
& Y; j: F6 M; ^" _- v4 ?7 q 在arm 下要使结构体按指定字节对齐,可行的方法
5 _ z( Q3 e+ D) X, k 1.在makefile里加-fpack-struct 选项,这样的话对所有的结构按一字节对齐. $ t: i% X, b5 u" Q6 ?% ^; @* \
不得不说,确实有那么些质量较差的程序可能需要你部分自然对齐,部分一字 节对齐,此时 ' U- q z9 D x( U- m
2. typedef struct pack{
& T3 d7 ~1 ~! n/ o R& N }__attribute__((packed))
- S( n1 M: j9 r) E 可利用__attribute__属性
! \8 G3 q* ]& ~4 Y# r 当然最后的方式,还是自己去看arm体系结构与gcc编译选项了。
9 x- l" a& E! I4 F I1 n4 a |
|