【问题标题】:stp aarch64 instruction must be used with "non-contiguous pair of registers"stp aarch64 指令必须与“非连续寄存器对”一起使用
【发布时间】:2014-08-08 04:01:52
【问题描述】:

aarch64 架构没有多重存储和加载指令,即没有来自 armv7 arch 的 stm 和 ldm 等价物。相反,您必须使用 stp 和 ldp 指令来存储和加载寄存器对。

根据ARM参考手册:

http://www.element14.com/community/servlet/JiveServlet/previewBody/41836-102-1-229511/ARM.Reference_Manual.pdf

没有多寄存器 LDM、STM、PUSH 和 POP 指令,但可以加载存储非连续寄存器对。

我的问题是,这里的非连续是什么意思?我的即时反应是,这意味着您不能在这些命令中使用连续编号的寄存器,例如

stp x0, x1, [sp, #-16]!

是非法的。但是我不相信这是事实。我已经看到示例代码正是这样做的,而且我设法让(Apple's)Clang 生成类似的代码,例如

stp x1, x0, [fp, #-16]!

我这辈子都想不出连续是什么意思。我认为这可能与使用重叠寄存器有关,例如

stp x0, x0, [sp, #-16]!
stp w0, x0, [sp, #-12]!

但是,我也看到过执行此类操作的示例代码(并不是说代码是正确的!)。如果是这种情况,我也会明确使用重叠而不是连续的术语。

有什么想法吗?

【问题讨论】:

  • stp w0, x0, [sp, #-12]! - SP 应该是 16 字节对齐的。 32b (wN) & 64b (xN) 寄存器不能混合在一个操作中

标签: assembly arm cpu-registers arm64


【解决方案1】:

它主要是强调与 A32 (ARM) LDRD/STRD 指令的对比*,它只能加载一对连续的寄存器,其中最低的必须是偶数,即:

LDRD r0, r1, [sp]   @ OK
LDRD r0, r7, [sp]   @ <Rt> and <Rt2> are non-contiguous: invalid
LDRD r3, r4, [sp]   @ Contiguous but <Rt> odd-numbered: invalid

[这是因为指令中只有一个空间可以对一个目标寄存器进行编码,因此架构必须有一种已定义的方式来推断第二个目标寄存器。]

相比之下,A64 LDP/STP 编码具有编码两个目标寄存器的空间,这意味着它们可以是任意顺序的任意两个寄存器,即它们允许不连续 - 这是一种许可,而不是限制。

请注意,自从完整的 ARMv8 ARM 发布以来,该特定文档为 obsolete,其中包含适当的详细说明页面,应该稍微不那么模棱两可。

* T32 (Thumb) 编码没有这个限制,因为缺少条件谓词意味着有空间来编码第二个目标寄存器,很像 A64。

【讨论】:

  • 太棒了,感谢您的清理。我的大脑坚持阅读它作为一种限制! :)
猜你喜欢
  • 1970-01-01
  • 2014-03-02
  • 2019-09-28
  • 2018-01-31
  • 2020-01-25
  • 2018-10-03
  • 2020-02-06
  • 2018-03-09
相关资源
最近更新 更多