我原本预计8位AVR平台不需要任何对齐。但是,我在an LLVM commit:
中找到了以下评论以前的数据布局在处理原子时会引起问题。
例如,加载小于16位的16位值是非法的 对齐。
这会更改数据布局,以便所有类型至少对齐 他们自己的宽度。
不幸的是,the original author of this commit isn't sure if that is right either:
自从我最初从SourceForge导入旧的SVN存储库以来,大多数对齐的东西都没有被触及。我没有处理过很多,所以我的知识很差。
最安全的假设是,如果某些事情看起来有意,那么可能不是; P
(8位)AVR的对齐故事究竟是什么?
答案 0 :(得分:4)
这条评论对我没有任何意义。 AVR本身并不知道16位类型,特别是对16位类型的原子访问,无论是否对齐。
在经典的AVR CPU上,不需要对齐16位数据,因为16位存储器访问总是评估为两个8位读取到两个寄存器。
但是,当使用某些AVR上可用的movw
指令将数据从一个寄存器对移动到另一个寄存器对时,存在一种“对齐限制” - 这里的寄存器编号较低的寄存器必须是偶数。这与内存对齐无关,但在构建编译器时可能会产生影响,也可能在尝试通过寄存器文件作为内存(最低32个RAM地址)访问寄存器内容时,这取决于编译器的实现方式。编译器可能会通过keepint选项打开来限制自身,以便能够通过对寄存器文件的存储器访问来访问寄存器中的16位值,这实际上需要字对齐。
当尝试写到程序存储器(Flash)时,会应用第二种“对齐限制” - 手册明确指出在“SPM指令中,应清除地址的最低有效位” ”。这是可以理解的,因为AVR的闪存是根据最小指令大小进行字寻址的。但是,您可以使用LPM指令对读取程序存储器进行字节寻址。由于所有AVR都不支持直接访问SPM,但我不知道这是否相关。 SPM和“原子类型”如何相互关联可以很好地解决问题 - 当写入访问程序存储器时,无论如何都必须通过禁用中断使整个访问成为原子。无论如何,gcc处理库中的程序存储器访问。
在这些特定情况(寄存器文件,程序存储器存储器)之外,AVR完全没有任何问题来访问奇数地址上的字值。