EDA365电子论坛网

标题: ARM内存边界对齐以及sizeof问题 [打印本页]

作者: monsterskyy    时间: 2021-3-22 14:01
标题: ARM内存边界对齐以及sizeof问题
默认情况下,在32位cpu里,gcc对于结构体的对齐方式是按照四个字节来对齐的。看以下结构体
/ T, ?8 t, _9 }2 n* e: R9 W/ r2 E! N  typedef struct pack{ / T) D' b+ n5 \* ^8 L3 }" v
  char a;
* y" Q- E9 J+ C0 v4 _  int b;
4 C( Z- a. f8 L) @' I  short c;
7 f' m% o" ?4 Z% S, U* L, N  }pack; ' u* H2 R; I; C+ x
  对于Pack结构体,默认情况下在arm/386平台下(别的平台没试过)sizeof(pack)=12,求解过程如下: ! y+ j& b# n( X- i9 @
  sizeof(char)=1;
! ^  e( ?* I# J0 O$ b. W5 e5 O  下一个int b,由于是四个字节,要求b的开始地址从32的整数倍开始,故需要在a后面填充3个没用的字节,记为dump(3),sizeof(b)=4,此时相当于结构体扩充为
- P* d! Z0 X7 }  char a;
$ w$ t' x; S; V5 [; v: e8 l1 ?  Q  char dump(3);
2 g# c) N  F- W" y  int b; , H/ W0 O1 l+ V! |! r0 x, _' X
  看short c,现在c的前面有8个字节,c是两个字节,c的开始地址是从16的整数开始,在b前面不需再加东西.此时对于结构体来说,sizeof(pack)=10,但是这不是最终结果,最后总的字节数也要能被4个字节整除,所以还需在short c后面再加 : N2 |. c+ g9 ]9 i# j
  dump(2);
, W1 \$ F) w3 L/ F5 s! z  故总的字节数为12.
  M! e) S  C6 C+ z  当然以上说的只是简单的情况,下面谈谈arm,x86在gcc里关于内存边界字节对齐的区别.对于同样的结构体,在386下
- ?# L% R/ n+ v7 Z  #prama pack(1) 6 Q9 P& f8 Y8 G
  后,sizeof(pack)=1 4 2=7
& {% O9 W' x' a* j2 l1 X1 N0 W4 N" r  而在arm下同样的操作sizeof(pack)=1 4 2 1=8,即虽然b根a之间不要填充但总的长度必须要是4的整数倍. . l4 v6 o5 ~2 a# k$ T, x+ O  ]
  在arm 下要使结构体按指定字节对齐,可行的方法 6 F* ?0 p( c- N) d
  1.在makefile里加-fpack-struct 选项,这样的话对所有的结构按一字节对齐. % l# g5 S' B, ?
  不得不说,确实有那么些质量较差的程序可能需要你部分自然对齐,部分一字 节对齐,此时
( Q7 n  V( k" d' b& h' O3 k  2. typedef struct pack{ : [  U! q/ f& _) M
  }__attribute__((packed))
" M5 f3 X, V( ~( |3 A2 i' _  可利用__attribute__属性 0 ~! a: [3 F, Z0 _5 S
  当然最后的方式,还是自己去看arm体系结构与gcc编译选项了。  R% b3 t7 |# K0 u

作者: freedom1    时间: 2021-3-22 14:49
ARM内存边界对齐以及sizeof问题,先收藏了。
作者: modengxian111    时间: 2021-3-22 15:00
就是容易出现问题,学习了




欢迎光临 EDA365电子论坛网 (https://bbs.eda365.com/) Powered by Discuz! X3.2