安庆大理运城常德铜陵江西
投稿投诉
江西南阳
嘉兴昆明
铜陵滨州
广东西昌
常德梅州
兰州阳江
运城金华
广西萍乡
大理重庆
诸暨泉州
安庆南充
武汉辽宁

嵌入式C语言自我修养地址对齐的核心思想

9月25日 无镇楼投稿
  嵌入式C语言自我修养地址对齐的核心思想
  7。1属性声明:aligned
  GNUC通过atttribute来声明aligned和packed属性,指定一个变量或类型的对齐方式。这两个属性用来告诉编译器:在给变量分配存储空间时,要按指定的地址对齐方式给变量分配地址。如果你想定义一个变量,在内存中以8字节地址对齐,就可以这样定义。
  intaattribute((aligned(8));
  通过aligned属性,我们可以直接显式指定变量a在内存中的地址对齐方式。aligned有一个参数,表示要按几字节对齐,使用时要注意地址对齐的字节数必须是2的幂次方,否则编译就会出错。
  什么是数据对齐
  一般情况下,当我们定义一个变量,编译器会按照默认的地址对齐方式,来给该变量分配一个存储空间地址。如果该变量是一个int型数据,那么编译器就会按4字节或4字节的整数倍对齐;如果该变量是一个short型数据,那么编译器就会按2字节或2字节的整数倍边界对齐;如果是一个char类型的变量,那么编译器就会按照1字节对齐。
  inta1;
  intb2;
  charc13;
  charc24;
  intmain(void)
  {
  printf(a:p,a);
  printf(b:p,b);
  printf(c1:p,c1);
  printf(c2:p,c2);
  return0;
  }
  在上面的程序中,我们分别定义2个int型变量,2个char型变量,然后分别打印它们的地址,运行结果如下。
  a:00402000b:00402004c1:00402008c2:004这个地址不是4字节对齐的。编译器空出3个字节单元,直接从0x0040200C这个地址上给变量c2分配存储空间。
  为什么要数据对齐?
  通过aligned这个属性声明,我们虽然可以显式指定变量的地址对齐方式,但是也会因边界对齐造成一定的内存空洞,浪费一定的内存空间。比如在上面这个程序中,0x004020090x0040200b这三个地址空间的存储单元就没有被使用。
  既然地址对齐会造成一定的内存空洞,那我们为什么还要按照这种对齐方式去存储数据呢?一个主要原因就是,这种对齐设置可以简化CPU和内存RAM之间的接口和硬件设计。比如一个32位的计算机系统,CPU读取内存时,硬件设计上可能只支持4字节或4字节倍数对齐的地址访问,CPU每次往内存RAM读写数据时,一个周期可以读写4个字节。如果我们把一个数据放在4字节对齐的地址上,那么CPU一次就可以把数据读写完毕;如果我们把一个int型数据放在一个非4字节对齐的地址上,那CPU就要分2次才能把这个4字节大小的数据读写完毕。
  为了配合计算机的硬件设计,编译器在编译程序时,对于一些基本数据类型,比如int、char、short、float等,会按照其数据类型的大小进行地址对齐,按照这种地址对齐方式分配的存储地址,CPU一次就可以读写完毕。虽然边界对齐会造成一些内存空洞,浪费一些内存单元,但是在硬件上的设计却大大简化了。这也是编译器给我们定义的变量分配地址时,不同类型变量按不同字节数地址对齐的原因。
  除了int、char、short、float这些基本类型数据,对于一些复合类型数据,也要满足地址对齐要求。
  7。2结构体的对齐
  结构体作为一种复合数据类型,编译器在给一个结构体变量分配存储空间时,不仅要考虑结构体内各个基本成员的地址对齐,还要考虑结构体整体的对齐。为了结构体内的成员地址对齐,编译器可能会在结构体内填充一些空间;为了结构体整体对齐,编译器可能会在结构体的末尾填充一些空间。
  接下来,我们定义一个结构体,结构体内定义int、char和short三种成员,并打印结构体的大小和各个成员的地址。
  structdata{
  
  
  
  }
  intmain(void)
  {
  
  printf(size:d,sizeof(s));
  printf(a:p,s。a);
  printf(b:p,s。b);
  printf(c:p,s。c);
  }
  程序运行结果如下。
  size:12
  s。a:0028FF30
  s。b:0028FF34
  s。c:0028FF38
  我们可以看到,因为结构体的成员b需要4字节对齐,编译器在给成员a分配完空间后,接着会空出3个字节,在满足4字节对齐的0x0028FF34地址处才给成员b分配存储空间。接着是short类型的成员c占据2字节的存储空间。三个结构体成员一共占据44210字节的存储空间,根据结构体的对齐规则,结构体的整体对齐要向结构体所有成员中最大对齐字节数或其整数倍对齐,或者说结构体的整体长度要为其最大成员字节数的整数倍,如果不是整数倍要补齐。因为结构体最大成员int为4个字节,或者说按4字节的整数倍对齐,所以结构体的长度要为4的整数倍,要在结构体的末尾补充2个字节,所以最后结构体的size为12个字节。
  结构体成员中,不同的排放顺序,可能也会导致结构体的整体长度不一样,我们修改一下上面的程序。
  structdata{
  
  
  
  };
  intmain(void)
  {
  
  printf(size:d,sizeof(s));
  printf(s。a:p,s。a);
  printf(s。b:p,s。b);
  printf(s。c:p,s。c);
  }
  程序运行结果如下。
  size:8
  s。a:0028FF30
  s。b:0028FF32
  s。c:0028FF34
  我们调整了一些成员顺序,你会发现,char型变量a和short型变量b,分配在了结构体的前4个字节存储空间中,而且都满足各自的地址对齐,整个结构体大小是8字节,只造成一个字节的内存空洞。我们继续修改程序,让short型的变量b按4字节对齐:
  structdata{
  
  shortbattribute((aligned(4)));
  
  };
  程序运行结果如下。
  size:12
  s。a:0028FF30
  s。b:0028FF34
  s。c:0028FF38
  你会发现,结构体的大小又重新变为12个字节。这是因为,我们显式指定short变量以4字节地址对齐,导致变量a的后面填充了3个字节空间。int型变量c也要4字节对齐,所以变量b的后面也填充了2个字节,导致整个结构体的大小为12字节。
  我们不仅可以显式指定结构体内某个成员的地址对齐,也可以指定整个结构体的对齐方式。
  structdata{
  
  
  
  }attribute((aligned(16)));
  程序运行结果如下。
  size:16
  s。a:0028FF30
  s。b:0028FF32
  s。c:0028FF34
  在这个结构体中,各个成员一共占8个字节。通过前面学习我们知道,整个结构体的对齐只要是最大成员对齐字节数的整数倍即可。所以这个结构体整体就以8字节对齐,结构体的整体长度为8字节。但是我们在这里,显式指定结构体整体以16字节对齐,所以编译器就会在这个结构体的末尾填充8个字节以满足16字节对齐的要求,导致结构体的总长度变为16字节。
  7。3思考:编译器一定会按照我们指定的大小对齐吗?
  通过aligned属性,我们可以显式指定一个变量的对齐方式,那么,编译器就一定会按照我们指定的大小对齐吗?非也!
  我们通过这个属性声明,其实只是建议编译器按照这种大小地址对齐,但不能超过编译器允许的最大值。一个编译器,对每个基本数据类型,都有默认的最大边界对齐字节数。如果你超过了,不好意思,我不奉陪,编译器只能按照它规定的最大对齐来给你的变量分配地址。
  charc13;
  charc2attribute((aligned(16)))4;
  intmain(void)
  {
  printf(c1:p,c1);
  printf(c2:p,c2);
  return0;
  }
  在这个程序中,我们指定char型的变量c2以16字节对齐,然后运行结果为:
  c1:00402000c2:00402010
  我们可以看到,编译器给c2分配的地址就是16字节地址对齐的,如果我们继续修改c2变量按32字节对齐,你会发现程序的运行结果不再会有变化,编译器还会分配一个16字节对齐的地址,因为已经超过编译器允许的最大值了。
  7。4属性声明:packed
  aligned属性一般用来增大变量的地址对齐,元素之间因为地址对齐会造成一定的内存空洞。而packed属性则与之相反,用来减少地址对齐,用来指定变量或类型使用最可能小的地址对齐方式。
  structdata{
  
  shortbattribute((packed));
  intcattribute((packed));
  };
  intmain(void)
  {
  
  printf(size:d,sizeof(s));
  printf(s。a:p,s。a);
  printf(s。b:p,s。b);
  printf(s。c:p,s。c);
  }
  在这个程序中,我们将结构体的成员b和c使用packed属性声明,就是告诉编译器,尽量使用最可能小的地址对齐给它们分配地址,尽可能地减少内存空洞。程序的运行结果如下。
  size:7
  s。a:0028FF30
  s。b:0028FF31
  s。c:0028FF33
  通过结果我们看到,结构体内各个成员地址的分配,使用最小1字节的对齐方式,导致整个结构体的大小只有7个字节。
  这个特性在底层驱动开发中还是非常有用的。比如,你想定义一个结构体,封装一个IP控制器的各种寄存器。在ARM芯片中,每一个控制器的寄存器地址空间一般是连续存在的。如果考虑数据对齐,结构体内有空洞,这样就跟实际连续的寄存器地址不一致了,使用packed就可以避免这个问题,结构体的每个成员都紧挨着依次分配存储地址,这样就避免了各个成员元素因地址对齐而造成的内存空洞。
  structdata{
  
  
  
  }attribute((packed));
  我们对整个结构体添加packed属性,和分别对每个成员添加packed属性,效果是一样的。修改结构体后,程序的运行结果跟上面程序运行结果相同结构体的大小为7,结构体内各成员地址相同。
  7。5Linux内核中aligned、packed属性声明
  在Linux内核中,我们经常看到aligned和packed一起使用,即对一个变量或类型同时使用aligned和packed属性声明。这样做的好处是,既避免了结构体内因地址对齐产生的内存空洞,又指定了整个结构体的对齐方式。
  structdata{
  
  
  
  }attribute((packed,aligned(8)));
  intmain(void)
  {
  
  printf(size:d,sizeof(s));
  printf(s。a:p,s。a);
  printf(s。b:p,s。b);
  printf(s。c:p,s。c);
  }
  程序运行结果如下。
  size:8
  s。a:0028FF30
  s。b:0028FF31
  s。c:0028FF33
  在这个程序中,结构体data虽然使用packed属性声明,整个长度变为7,但是我们同时又使用了aligned(8)指定其按8字节地址对齐,所以编译器要在结构体后面填充1个字节,这样整个结构体的大小就变为8字节,按8字节地址对齐。
投诉 评论 转载

人类目前对宇宙的探索才发现地球是多么的渺小曾经的我们,认为脚下的土地包围天空与日月;后来哥白尼一语道破,我们的地球只是天空下的一隅,我们生存的星球围绕着空中的太阳运行;再后来我们发现太阳系之外有广阔银河,银河外还有更加……快收藏转发给家人醒酒可以做的5个小技巧人与人之间的关系很微妙,距离是近是远,交情是薄是厚,有时候尺子丈量不出来,但酒可以。喝酒的传统,大概可以追溯到殷商时代的酒池肉林,直到现在,空前而不绝后地充分发挥了酒在中……当孩子说我累了,不想学高情商妈妈一开口,他就心服口服放假这段时间,我和儿子一起商量制定了假期计划。其中很重要的一项,就是每天都有数学专项提升训练。他数学不是很好,最初还肯好好配合,昨天突然闹起脾气,让做题也一百个不情……广东江门11月房价出炉,新房价格下跌,恩平市房价最低根据安居客的数据,2022年11月,江门新房均价8665元,环比上月下跌1。14。从半年来的房价走势曲线可以看出,江门新房价格从6月份开始下跌,至11月房价岀炉,已经五连跌。其……嵌入式C语言自我修养地址对齐的核心思想嵌入式C语言自我修养地址对齐的核心思想7。1属性声明:alignedGNUC通过atttribute来声明aligned和packed属性,指定一个变量或类型的对齐……当代散文鏊子煎饼文朱玉富记忆就像一条奔流不息的河,左岸封存着过去的完美回忆,右岸储蓄我执着追寻的未来。就这样平静的流淌着,点点滴滴的尘埃随着流沙远去!磨盘在窗户的外面,木头格子的窗户糊着……作为人类终极能源的可控核聚变,中美之间的差距在哪?当地时间12月13日,美国能源部宣布:LLNL通过国家点火装置的实验获得成功,聚变反应产生了大约2。5兆焦耳能量,是激光所消耗2。1兆焦耳能量的120,在核聚变领域取得了突破性……魔幻!突然暴跌70!基金公司沦为接盘侠!300多万打水漂!更新净值后跌70,这只债基怎么了?成立一年便沦为僵尸基金,1000万元砸在手中近4年,这只基金经历了什么?700万元被套近4年,这家基金公司苦心自救自家基金却成接盘……罗布泊复活了,曾经的原子弹试验场,现在可养活亿万中国人中国作为一个历史悠久的华夏民族,千百年来衍生出了许多令人叹为观止的文明。加之幅员辽阔,地大物博,也造就了许多惊人的地貌。这些有趣的文明,更是为华夏蒙上了一层神秘的面纱,随着时间……世界杯后,FIFA排名大洗牌,阿根廷仅第二,日本称霸,国足创世界杯随着阿根廷捧杯而圆满落幕,这样一来,2022年所有的国家队比赛全部结束。如今,国家队年终排名已经呼之欲出,世界足坛的格局再次产生了重要变化。首先来看阿根廷队,作为世……马斯克特斯拉员工每周在公司呆够40个小时才能在家办公否则走人Tech星球6月1日消息,据新浪科技,特斯拉CEO埃隆马斯克(ElonMusk)似乎已经受够了在家办公模式。他今日在一封电子邮件中表示,特斯拉员工要想在家办公,每周至少要在办公……比特币以太坊在CPI上涨后一夜之间清算1。17亿美元对于比特币和以太坊来说,这是动荡的一周,因为在乐观的CPI报告之后两者都上涨,只是看到这些收益在一夜之间消失了。比特币和以太坊刚刚放弃了本周乐观的CPI报告后获得的所有新……
雷军也没想到,3年前这个老掉牙的小米音箱还能看电视别老穿黑白灰!今年更流行穿枯叶棕,显白时髦又洋气让梦萌芽,爬满篱笆中国豪华列车走红,上万元一张票值得吗?旅客很新鲜的体验微信聊天骚操作,这些暗号只有内行才懂荣耀70Pro同款芯片256GB120Hz屏5000mAh,幸福离我们有多远三国杀为了土豪玩家的体验感,又一项针对穷人玩家的新功能出现脾虚湿气重齿痕舌胀气,5个中成药健脾祛湿消胀黄圣依真有贵妇感,穿低胸薄纱连衣裙,魔鬼身材太令人心动戴安娜王妃的10件绝美华服,英伦玫瑰名不虚传,每一套都是经典法国vs摩洛哥想起这件事我就后悔喝茶时需要注意哪些小细节?划分南北方的分界线是什么?秋游雨花台200字学生作文宝宝洗护不当易患泌尿系统疾病妈妈们需多上心热巴纯天然美貌实锤,10岁跳舞视频曝光,五官精致身姿苗条生活技能大起诉离婚没有出生证是否影响抚养权什么是u形地漏专利许可有哪几种方式?一杯水帮你降降火陕西古墓被大蛇保护,无人敢靠近,专家试图揭谜却发现更大谜团

友情链接:中准网聚热点快百科快传网快生活快软网快好知文好找七猫云易事利