|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
默认情况下,在32位cpu里,gcc对于结构体的对齐方式是按照四个字节来对齐的。看以下结构体
- u$ z' x4 o% [/ K. G2 g, S) q2 P
9 h+ r8 p+ T |6 c/ N
7 e& r9 U1 H: d% d typedef struct pack{( _0 x6 d2 E" }
) g4 Q2 S. a+ T! ]9 a: O3 {5 ~
char a;
0 `6 y, o* J y. M3 |( v. }( v" i8 _/ \
int b;. w$ Z! D$ J; j3 D. {
6 W. ?: }# {. g7 ]4 W, o* | short c;
/ K0 Q) V+ a2 ~/ O" _( p7 F/ g# l5 b4 e0 j
}pack;) f9 M3 V# @. W% S' B
; c4 t4 ?, f/ H8 S7 Q; _
对于Pack结构体,默认情况下在arm/386平台下(别的平台没试过)sizeof(pack)=12,求解过程如下:' w3 D9 {% y$ c
, _; S( C/ O" x0 @# ~6 _% l sizeof(char)=1;
& t1 _8 ]# e9 Q9 i& a/ M2 B6 `8 K# M; `- }; F5 L0 n
下一个int b,由于是四个字节,要求b的开始地址从32的整数倍开始,故需要在a后面填充3个没用的字节,记为dump(3),sizeof(b)=4,此时相当于结构体扩充为8 R: }( `! P3 s- ~, m
, v, \9 z3 ?' x char a;
1 _$ ?+ \ A$ B9 u; d4 b: B
; n2 |& I: i7 V6 b: e4 U char dump(3);
/ S( b/ B) y( S
& ?5 |- E! \; \& v3 u1 ~1 M int b;
+ G/ S# L+ I! X2 a- |' _" |( l4 S" l, | w. C, W+ y
看short c,现在c的前面有8个字节,c是两个字节,c的开始地址是从16的整数开始,在b前面不需再加东西.此时对于结构体来说,sizeof(pack)=10,但是这不是最终结果,最后总的字节数也要能被4个字节整除,所以还需在short c后面再加6 \. \/ A/ B. D& `/ X. a+ g9 N9 D
, B0 p2 \; M# r% B dump(2);$ [7 [( W$ T5 c* v
$ B5 W1 L) a8 f6 o5 @- t. y" T7 A/ Y 故总的字节数为12.5 b8 N( ?) Z- Z% ]* u6 x
6 ^; o0 V- z( z 当然以上说的只是简单的情况,下面谈谈arm,x86在gcc里关于内存边界字节对齐的区别.对于同样的结构体,在386下
/ p9 o: B3 c' G3 I
" \7 j% C& |( M% i1 c4 m* e7 W# M' T #prama pack(1)
# P) @, b H( v! G: |, z# E; T1 ^7 ~: p- A# F# T- }
后,sizeof(pack)=1 4 2=7
1 i" r. F+ h- c4 e; P* I5 ]4 T8 K9 z/ w2 G& S! Y
而在arm下同样的操作sizeof(pack)=1 4 2 1=8,即虽然b根a之间不要填充但总的长度必须要是4的整数倍.
3 j4 g" X+ A5 h0 X
2 O$ o0 y9 M* \5 H 在arm 下要使结构体按指定字节对齐,可行的方法6 N! R- D4 n' D# }* P+ y2 f* z+ C
) A* x# J6 H1 d
1.在makefile里加-fpack-struct 选项,这样的话对所有的结构按一字节对齐.
0 ?6 \8 b. A+ Y
8 K I( K m0 @" V8 F2 M 不得不说,确实有那么些质量较差的程序可能需要你部分自然对齐,部分一字 节对齐,此时
, U9 ~5 x3 |/ t( ~; h& o# b* T0 a: V( F4 Q
2. typedef struct pack{
; v! V( q! N* w" N0 H! n1 z! L: [- L5 g4 _4 ?$ C! ]' x) T% `
}__attribute__((packed))
6 X* A9 l( k b, N/ F8 o. c6 F. [& [# n/ r: t$ j. s
可利用__attribute__属性4 M a: d& R% S5 Q$ @3 Z; a
9 T3 h- x) C. b, s 当然最后的方式,还是自己去看arm体系结构与gcc编译选项了。
4 f/ Z; V2 ]' \- Y( X: A, o4 [+ e' [
|
|