|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
默认情况下,在32位cpu里,gcc对于结构体的对齐方式是按照四个字节来对齐的。看以下结构体 3 {6 ~) Q8 x: c4 J6 R, z
typedef struct pack{
" T. n; g) u; }4 _ char a; 0 {; f- Z% D8 H$ V8 C f% K _
int b;
( m1 a L, A* N5 u2 \ short c; ' U. k0 m% ?7 t% R. B9 ~/ ?3 C
}pack; 2 v4 t. h9 \" m t% P
对于Pack结构体,默认情况下在ARM/386平台下(别的平台没试过)sizeof(pack)=12,求解过程如下:
* A9 g# W5 T5 b2 ^2 _ R3 r sizeof(char)=1;
& k2 |( U; W( k2 x 下一个int b,由于是四个字节,要求b的开始地址从32的整数倍开始,故需要在a后面填充3个没用的字节,记为dump(3),sizeof(b)=4,此时相当于结构体扩充为
1 L( m/ ?2 n; g5 ]4 r& e char a;
( v) c- x3 S/ W% r/ a1 ?/ [2 R char dump(3);
- k" N1 g7 n# Q. ?& y' x* Q int b;
7 H4 H" z q& S/ F+ t4 {, |$ [ 看short c,现在c的前面有8个字节,c是两个字节,c的开始地址是从16的整数开始,在b前面不需再加东西.此时对于结构体来说,sizeof(pack)=10,但是这不是最终结果,最后总的字节数也要能被4个字节整除,所以还需在short c后面再加 / x$ B, J1 X2 `3 E
dump(2); 5 n- n6 ~. ?$ Z3 f, N2 o* c
故总的字节数为12. ' M7 I/ B7 g; U1 y7 F3 x4 J
当然以上说的只是简单的情况,下面谈谈arm,x86在gcc里关于内存边界字节对齐的区别.对于同样的结构体,在386下
4 @& s" J3 M% Z7 x: E- r0 M #prama pack(1)
0 C( d* P; c" K 后,sizeof(pack)=1 4 2=7
; H, Q* H- A" [ 而在arm下同样的操作sizeof(pack)=1 4 2 1=8,即虽然b根a之间不要填充但总的长度必须要是4的整数倍. : K- i f1 _2 k
在arm 下要使结构体按指定字节对齐,可行的方法
$ y% L* R1 K) R- j2 e9 ~& ~" W2 f9 @ 1.在makefile里加-fpack-struct 选项,这样的话对所有的结构按一字节对齐.
! X' I$ |" x( s; s5 V# n( ^ 不得不说,确实有那么些质量较差的程序可能需要你部分自然对齐,部分一字 节对齐,此时
* R$ h+ S+ I, t: S; d. E7 f! p 2. typedef struct pack{
1 T& Z7 ?/ ~& x- G }__attribute__((packed))
! I% Z7 ?# C2 P2 S' j, h 可利用__attribute__属性 - \) A0 y) g' }6 y+ a" _8 s. y
当然最后的方式,还是自己去看arm体系结构与gcc编译选项了。
+ C5 V5 T0 s/ @. l% ]+ ^$ A |
|