为什么“ARM 架构的过程调用标准”(AAPCS) 要求 SP 8 字节对齐?

aus*_*len 5 assembly arm abi calling-convention stack-pointer

由于这是一个反复出现的话题,所以我提出了一个关于它的问题。

根据AAPCS

5.2.1.1 通用堆栈约束

  • SP mod 4 = 0。堆栈必须始终与字边界对齐

5.2.1.2 公共接口的堆栈约束

  • SP mod 8 = 0。堆栈必须双字对齐。

8字节对齐背后的原理是什么?

Nic*_*rth 5

主要原因是STRD和LDRD只能工作在8字节对齐的地址上。因此,要在堆栈变量上使用它们,堆栈指针需要始终保持 8 字节对齐。

引用ARM 网站

八字节堆栈对齐对于支持 LDRD 和 STRD 指令的处理器特别有利,例如基于 ARM 架构 v5TE 及更高版本的处理器。如果堆栈不是八字节对齐的,则使用 LDRD 和 STRD 可能会导致对齐错误,具体取决于所使用的目标和配置。

ARM 还在本ABI 建议说明中详细解释了这一点。


art*_*ise 1

可能的原因有很多;

\n\n
    \n
  1. 工具需要它。
  2. \n
  3. ldrd/strd在某些架构上需要它。
  4. \n
  5. 许多 ARM 总线都是 64 位宽。8 字节对齐将导致更快的内存访问。
  6. \n
  7. 高速缓存也是对齐的,并且通常比 64 位(128B、1024b)更宽。
  8. \n
  9. 页表和 TLB 将跨越大于 64 位(1k 或 4k+)的大小。
  10. \n
  11. 标记指针可用于异常(C++、信号等)帧遍历代码。八字节对齐允许使用额外的位。
  12. \n
\n\n

唯一重要的是,标准是这么说的。如果您不遵守此规定,您的编译器和工具将无法互操作。主要是第 1 项意味着这些工具不会互操作。该代码将获取错误的值,或者将引发机器异常。如果异常处理代码使用第 5 项,它也可能会破坏事情。

\n\n

主要是,有人做出选择的事实意味着人们可以利用这一事实进行他们喜欢的任何用途,并且仍然可以进行互操作。编译器将遵循标准的建议,因为它们需要与可能不是由它们生成的其他库和代码进行互操作。

\n\n

还需要注意的是,这适用于 ARMv7/A。例如,Cortex M3 (CM3_r0) 的修订版 0 在进入异常时不会将 SP 与 8 的倍数对齐。

\n\n

ARM\xc2\xae 架构的 ABI 建议说明 \xe2\x80\x93 SP 在进入 AAPCS 时必须是 8 字节对齐 - 符合功能

\n