前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >漫谈C变量——对齐(3)

漫谈C变量——对齐(3)

作者头像
GorgonMeducer 傻孩子
发布2020-07-28 09:46:28
4950
发布2020-07-28 09:46:28
举报
文章被收录于专栏:裸机思维裸机思维

【正文】


  前面的两篇文章,我们分别介绍了“为什么变量要对齐到它的尺寸大小”,“编译器会怎么处理内存的对齐问题”以及“非对齐是如何产生的和非对齐的后果”,感觉自己错过了重要内容的朋友可以发送关键字“对齐”来复习一下。下面我们来介绍几个于对齐相关的问题:

1. 结构体的对齐

  在ARM Compiler里面,结构体内的成员并不是简单的对齐到字(Word)或者半字(Half Word),更别提字节了(Byte),结构体的对齐使用以下规则:

  • 整个结构体,根据结构体内最大的那个元素来对齐。比如,整个结构体内部最大的元素是WORD,那么整个结构体就默认对齐到4字节。
  • 结构体内部,成员变量的排列顺序严格按照定义的顺序进行
  • 结构体内部,成员变量自动对齐到自己的大小——这就会导致空隙的产生。 比如:

struct { uint8_t a; uint16_t b; uint8_t c; uint32_t d; } Example;

  • 结构体内部,成员变量可以单独指定对齐方式为byte,例如

struct { uint8_t a; uint16_t b __attribute__ ((packed)); uint8_t c; uint32_t d; } Example;

效果就会变成:

2. Cortex-M 中断向量表的对齐

  Cortex-M中断向量表保存的都是32位的地址,每一个地址指向一个中断处理程序,因此中断向量表的大小必然是4的整倍数。理论上,你有n个中断,就因该有(n+1)*4 个字节大小的中断向量表。然而事情并非这么简单。为了硬件实现的方便

  • 中断向量表的大小必须是2^n (6<n<12) ,也就是128B,256B,512B, 1024B,2048B之一
  • 中断向量表的地址必须要对齐到它的大小,比如512Byte大小的中断向量表,其首地址必须要对齐到 0x0200(是0x200的整数倍)

  为什么会存在这样的限制呢,原因很简单,假设向量号为x的中断被触发了,Cortex-M内核就会用这个x作为下标去访问这个uint32_t的数组,那么这个中断向量具体在内存里面的地址如何计算的呢?

我们认为是这样的:

中断向量地址 = 向量表基地址 + (x * 4)

然而,我们天真了,为了省事,这里的“+”运算被替换成了简单的"或"运算,也就是说,实际的硬件实现是这样的:

中断向量地址 = 向量表基地址 OR (x *4)

这意味着什么呢?加法运算是会进位的!或运算不会。举例来说:

0x01 OR 0x01 = 0x01

0x01 + 0x01 = 0x02

当硬件认为系统中向量表应该是512个字节大小时,如果向量表的基地址(通过SCB->VTOR寄存器设置)对齐到了0x0200,那么或运算的结果就与加法是等效的——原因很简单,(x * 4) 的部分不会超过0x0200,因而与加法等效。反之就有问题了。

又由于系统强制要求中断向量表必须最少对齐到128个字节,那么对一个512字节大小的向量表来说,如果仅对齐到128个字节会发生什么呢?——如果前31个中断(包括系统自己的异常)触发了,系统可以正常处理,从第32个中断开始,任何一个触发,系统一定会出错——中断向量的所在的位置算错啦!(注意不是中断处理程序的地址算错了,是保存中断处理程序地址的那个向量所在的内存地址被算错了)

3. Cortex-M MPU 受保护内存区块的对齐

MPU也许你听说过,但你多半没有用过,因为“太!难!用!拉!”,为了硬件实现的方便,MPU每一个Region的设置被加入了一个人为的限制:

  • Region的大小必须是 2^n (4<n<33),也就是32,64...2G, 4G
  • Region的基地址必须对齐到它的大小

又来!是的,就是这么坑,所以如果你想用MPU保护一个任意位置任意大小的Memory,比如stack,不好意思,你要用很多个Region一起来拼接……具体怎么拼,说起来都麻烦,何况用……算了不说了。

好消息是,最新的ARMv8-M终于改进了这个反人类的设计,允许用户通过起始地址+终止地址的方法设定任意大小任意位置的Region(当然Region大小必须是32的倍数,这个地址也必须是32的倍数)。可以好好松口气了。

————————以上正文结束———————————

如果你喜欢我的思维,欢迎订阅 裸机思维

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-05-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 裸机思维 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档