|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
默认情况下,在32位cpu里,gcc对于结构体的对齐方式是按照四个字节来对齐的。看以下结构体( p" j. `8 ]$ ?% h1 u" Y. Y B
8 y2 k9 }2 F$ a2 C
/ m( [9 j* B1 P% h typedef struct pack{
( n/ H9 y+ d5 e- Q( B6 T5 Y1 p9 w3 J' M4 L2 S6 c( K0 o
char a;
( p! I: }! A: X" `: p3 W7 a" q) _
& ?! u" G0 V% l int b; e3 a4 X0 e. q% v L' z
$ M8 F* t1 e0 L
short c;% Y, Q: E9 ^& x' i0 L3 f
4 J: n, P+ d0 x1 L9 ]" { }pack;
! C4 V9 L* S' v# y6 U3 X* } O+ W$ o# h4 X
对于Pack结构体,默认情况下在arm/386平台下(别的平台没试过)sizeof(pack)=12,求解过程如下:
) \) D$ i! _3 p3 L% ^* g) c' ^# ]6 G' l% x- f
sizeof(char)=1;5 L2 C8 l* R7 Q. x) a
! V/ } q6 ]- ?: j* C 下一个int b,由于是四个字节,要求b的开始地址从32的整数倍开始,故需要在a后面填充3个没用的字节,记为dump(3),sizeof(b)=4,此时相当于结构体扩充为
* {4 h. O+ d6 g. c
0 ~5 x* D3 k6 x( g3 N char a;
8 o- t( w# z$ s0 T4 d8 l# F# r4 _! x1 R/ \7 s+ c, v, I
char dump(3);
, e& J% ^ k5 G( ^1 O C, b- H
W/ N- r" N. Q; D: O" X int b;
2 B8 l4 F8 [' k) g8 i/ g) v4 {
, O' n3 x, `7 W% \5 k+ W# a 看short c,现在c的前面有8个字节,c是两个字节,c的开始地址是从16的整数开始,在b前面不需再加东西.此时对于结构体来说,sizeof(pack)=10,但是这不是最终结果,最后总的字节数也要能被4个字节整除,所以还需在short c后面再加/ }# c4 z3 l# v
0 j7 T% ^. G; h
dump(2);
) m; N+ r8 G3 t. B& D2 r% o+ A& P/ R6 R$ b {
故总的字节数为12.
# z( W* K; w) h' Z+ k0 r; A& {6 i* e( X
当然以上说的只是简单的情况,下面谈谈arm,x86在gcc里关于内存边界字节对齐的区别.对于同样的结构体,在386下
* u9 m! I7 u4 A. Y4 E9 e
: M. U' n6 Z/ ^: G #prama pack(1)0 d' c7 A8 q5 c9 I- Q3 F
9 k* N7 }% d* ^3 p j" ^, U
后,sizeof(pack)=1 4 2=7
" R) d8 e) B; @" T# u; d" c1 O O7 F5 K9 \4 [8 F
而在arm下同样的操作sizeof(pack)=1 4 2 1=8,即虽然b根a之间不要填充但总的长度必须要是4的整数倍.! n. m N+ x0 F) I- o
/ m8 K# M9 J- e, L5 y$ F, ?2 Q
在arm 下要使结构体按指定字节对齐,可行的方法
" h; \ q; g% _) ?# I9 ]% O4 x$ q7 G. n1 E1 r$ B9 a& {
1.在makefile里加-fpack-struct 选项,这样的话对所有的结构按一字节对齐.% T3 [7 ?- @0 h+ P9 v
9 U! F) |7 Y- _+ t( O, j7 H8 Q+ b+ ? 不得不说,确实有那么些质量较差的程序可能需要你部分自然对齐,部分一字 节对齐,此时
" A9 D& O* J. Y9 l- h; a
' O# S" N$ x+ n% M. \4 G 2. typedef struct pack{% A! s' `) ~( f1 _# D% c
3 x |0 E Y9 |. I& {% Z
}__attribute__((packed))/ F' ~* R- a1 H1 s i
" |1 y% H% B8 q* B; v0 ]- Y/ a& ^
可利用__attribute__属性
7 n) T' g: q# U$ M- }- q) }; r
5 X- r$ o( p H7 L9 T- u; l; k 当然最后的方式,还是自己去看arm体系结构与gcc编译选项了。
4 t* M6 y0 D1 m! e/ z2 c; s) C6 R8 K- Y# j0 f3 p9 x" z
|
|