【问题标题】:What alignment is needed on 8-bit AVR?8 位 AVR 需要什么对齐?
【发布时间】:2017-05-24 13:46:15
【问题描述】:

我原以为 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 的对齐故事到底是什么?

【问题讨论】:

  • 我不知道 LLVM 的 AVR ABI,但 gcc 会在寄存器和堆栈中对函数参数进行一些填充,请参阅 gcc.gnu.org/wiki/avr-gcc#line-124
  • @JimmyB:但该链接不是只讨论 register number 对齐方式,与他在回答中解释的方式相同吗?
  • @JimmyB:具体来说,它说“如果当前参数在内存中传递,则停止该过程:所有后续参数也将在内存中传递。”但是它有没有说过内存中传递的参数是否对齐?
  • 注意 AVR 寄存器也被内存映射到寄存器文件中。因此,寄存器编号对齐也可以显示为内存对齐,以防你通过RAM的低32字节内存实现寄存器访问。对于编译器,这可能是一个限制。

标签: avr memory-alignment abi


【解决方案1】:

这个评论对我来说没有任何意义。 AVR 本身不知道 16 位类型,特别是不原子访问 16 位类型,无论任何对齐方式。

在经典 AVR CPU 上,不需要对齐 16 位数据,因为 16 位内存访问总是计算为对两个寄存器进行两次 8 位提取。

但是,当使用某些 AVR 上可用的 movw 指令将数据从一个寄存器对移动到另一个寄存器时,存在一种“对齐限制” - 这里是较低的 寄存器编号寄存器必须是偶数。但是,这与内存对齐无关,但可能会在构建编译器时产生影响,并且可能还会在尝试通过寄存器文件作为内存(最低 32 个 RAM 地址)访问寄存器内容时产生影响,具体取决于编译器的实现方式。编译器可能会通过将选项保持打开来限制自己,以便能够通过对寄存器文件的内存访问来访问寄存器中的 16 位值,这确实需要字对齐。

尝试写入到程序存储器(闪存)时适用第二种“对齐限制” - 手册明确指出,在“SPM 指令中,应清除地址的最低有效位”。这是可以理解的,因为 AVR 的闪存是根据最小指令大小进行字寻址的。但是,您可以使用 LPM 指令读取程序存储器字节寻址。由于不是所有 AVR 都支持直接访问 SPM,但我不知道这是否相关。 SPM 和“原子类型”如何相互关联很好 - 当写入访问程序内存时,无论如何必须通过禁用中断使整个访问成为原子访问。无论如何,gcc 会处理库中的程序内存访问。

在这种特殊情况(寄存器文件、程序存储器存储)之外,AVR 绝对没有任何问题来访问奇数地址上的字值。

【讨论】:

  • 好的,这看起来和我预期的一样;在关闭所有对齐后,我设法编译了一个重要的代码库。但是,在有某种权威参考之前,我不愿意接受这个答案。我开始认为我找不到任何关于对齐的黑白参考的原因仅仅是因为没有对齐;但很高兴看到对此的明确声明。
  • 您可能会发现与 Z80 或 6502 一样多的对 AVR 和内存对齐要求的引用......但是请注意,在我思考了一下之后,我对答案的扩展有关此问题的更多信息。
猜你喜欢
  • 2014-03-30
  • 1970-01-01
  • 2012-10-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-23
相关资源
最近更新 更多