6

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]!

但是,我也看到示例代码也在做这种事情(并不是说代码是正确的!)。如果是这种情况,我也会明确使用术语重叠而不是连续的。

有任何想法吗?

4

1 回答 1

15

它主要是强调与 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发布以来,该特定文档已过时,该文档具有适当的详细说明页面,应该稍微不那么模棱两可。

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

于 2014-08-08T09:07:03.330 回答