ARM的对齐规则

[复制链接]
baicai 发表于 2018-8-14 09:38:31 | 显示全部楼层 |阅读模式
本帖最后由 baicai 于 2018-8-14 09:39 编辑

对齐规则
每个特定平台上的编译器都有自己的默认“对齐系数”(也叫对齐模数)。程序员可以通过预编译命令#pragma pack(n),n=1,2,4,8,16来改变这一系数,其中的n就是你要指定的“对齐系数”。
  • [size=1.25]数据成员对齐规则:结构(struct)(或联合(union))的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员的对齐按照#pragma pack指定的数值和这个数据成员自身长度中,比较小的那个进行。
  • [size=1.25]结构(或联合)的整体对齐规则:在数据成员完成各自对齐之后,结构(或联合)本身也要进行对齐,对齐将按照#pragma pack指定的数值和结构(或联合)最大数据成员长度中,比较小的那个进行。
  • [size=1.25]结合1、2颗推断:当#pragma pack的n值等于或超过所有数据成员长度的时候,这个n值的大小将不产生任何效果



举例
对于如下平台
sizeof(unsigned char) = 1
sizeof(unsigned short) = 2
sizeof(unsigned int) = 4

例子1  typedef struct _t {
  ​
      unsigned char a;
      unsigned short b;
      unsigned int c;
      unsigned char d[11];
  }t_t;
  ​
  int main(int argc,char * argv[]){
  ​
      t_t t;
  ​
      printf("&(t.a) = %p\r\n&(t.b) = %p\r\n&(t.c) = %p\r\n&(t.d) = %p\r\nsizeof(t_t) = %d\r\n",&(t.a),&(t.b),&(t.c),&(t.d),sizeof(t_t));
      return 0;
  }
  ​
  /*
      &(t.a) = 0x7ffd317bc950
      &(t.b) = 0x7ffd317bc952
      &(t.c) = 0x7ffd317bc954
      &(t.d) = 0x7ffd317bc958
      sizeof(t_t) = 20
  */
例子2  #include <stdio.h>
  ​
  typedef struct _t {
  ​
      unsigned char a;
      unsigned int b;
      unsigned short c;
      unsigned char d[11];
  }t_t;
  ​
  int main(int argc,char * argv[]){
  ​
      t_t t;
  ​
      printf("&(t.a) = %p\r\n&(t.b) = %p\r\n&(t.c) = %p\r\n&(t.d) = %p\r\nsizeof(t_t) = %d\r\n",&(t.a),&(t.b),&(t.c),&(t.d),sizeof(t_t));
      return 0;
  }
  ​
  /*
      &(t.a) = 0x7ffdf31e6730
      &(t.b) = 0x7ffdf31e6734
      &(t.c) = 0x7ffdf31e6738
      &(t.d) = 0x7ffdf31e673a
      sizeof(t_t) = 24
  */

例子3  #include <stdio.h>
  ​
  #pragma pack(1)
  typedef struct _t {
  ​
      unsigned char a;
      unsigned int b;
      unsigned short c;
      unsigned char d[11];
  }t_t;
  #pragma pack()
  ​
  int main(int argc,char * argv[]){
  ​
      t_t t;
  ​
      printf("&(t.a) = %p\r\n&(t.b) = %p\r\n&(t.c) = %p\r\n&(t.d) = %p\r\nsizeof(t_t) = %d\r\n",&(t.a),&(t.b),&(t.c),&(t.d),sizeof(t_t));
      return 0;
  }
  ​
  /*
      &(t.a) = 0x7ffc5fc9f280
      &(t.b) = 0x7ffc5fc9f281
      &(t.c) = 0x7ffc5fc9f285
      &(t.d) = 0x7ffc5fc9f287
      sizeof(t_t) = 18
  */

总结
  • [size=1.25]例1和例2中互换b和c的类型,导致整个结构体长度都变大
  • [size=1.25]例3中通过#pragma pack()按一个字节对齐之后的变化






上一篇:2018年8月14日签到记录贴
下一篇:STM32L431之SPI从模式使用DMA时数据偏移3个字节

本版积分规则

QQ|Archiver|手机版|小黑屋|RD之家 - 研发工程师的伊甸园 ( 京ICP备18037383号 )
360导航 360安全浏览器 蚂蚁搜索 速搜全球 酷帝网站目录 搜狗导航 114啦网址导航

GMT+8, 2018-9-23 10:17

Powered by Discuz! X3.4

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表