ARM v8 中的 LDUR 和 STUR

Plu*_*ium 10 assembly arm armv8

我上过几门涉及 ARMv8 汇编的课程,但是两位老师都以不同的方式描述了 LDUR/STUR 指令,现在我已经迷失了方向。有人可以帮忙澄清一下吗?

如果我有指令:

LDUR R3, [R1, #8]
Run Code Online (Sandbox Code Playgroud)

我将把答案放在 R3 中,但是我从 R1 中得到了什么以及偏移量如何运作?这就像一个逻辑转变吗?ARM 手册将其描述为“字节偏移量”,但并未描述该偏移量如何在 R1 上运行。我是否移动了存储在 R1 中的值(比如 R1 的值是 50),还是我需要考虑 R1 之外的内存地址?其他消息来源说我需要以某种方式将 R1 视为一个数组?

Gui*_*rmo 16

LDUR 是Load (unscaled) Register。它从一个地址加上一个寄存器的偏移量加载一个值(32 位或 64 位)。unscaled意味着在机器代码中,偏移量不会ldr使用一样使用缩放偏移量进行编码,即不会对立即偏移位应用移位。偏移量(simm签名立即数)将添加到基址寄存器Xn|SP 中

因此,可以使用不是 4 或 8 倍数的位移 与ldur不同,与ldr

这些是 LDUR 的原型:

    -- loads a 32-bit value
    LDUR <Wt>, [<Xn|SP>{, #<simm>}]

    -- loads a 64-bit value
    LDUR <Xt>, [<Xn|SP>{, #<simm>}]
Run Code Online (Sandbox Code Playgroud)

STUR 是存储(未缩放)寄存器,工作方式相同,但它将寄存器中的值存储到内存中。

这些是 STUR 的原型:

    -- stores a 32-bit register
    STUR <Wt>, [<Xn|SP>{, #<simm>}]

    -- stores a 64-bit register
    STUR <Xt>, [<Xn|SP>{, #<simm>}]
Run Code Online (Sandbox Code Playgroud)

LDUR/STUR 允许访问与操作数大小对齐的32/64 位值。例如,存储在地址 0x52 处的 32 位值。


在你的例子中,

    LDUR R3, [R1, #8]
Run Code Online (Sandbox Code Playgroud)

该指令将加载到加字节R3指向的值。这就是 ARM 参考手册的意思。因此,如果 持有该值,这将加载存储在地址处的值。的值不会被修改。R18byte offsetR10x500x58R1


指令LDR R3, [R1, #8]LDR(立即)无符号偏移变体)产生相同的操作,然而,原型不同的是:

-- loads a 32-bit value
LDR <Wt>, [<Xn|SP>{, #<pimm>}]

-- loads a 64-bit value
LDR <Xt>, [<Xn|SP>{, #<pimm>}]
Run Code Online (Sandbox Code Playgroud)

直接偏移pimm不同,LDUR使用simm。这意味着以不同的方式解释偏移量。第一个 ( pimm ) 是一个正偏移量,它的范围对于 32 位变体和 64 位变体是不同的。

在 32 位版本中:

  • 它的范围从 0 到 16380,并且只能是 4 的倍数

在 64 位版本中:

  • 它的范围从 0 到 32760,并且只能是 8 的倍数

这意味着 LDUR 和 LDR(立即)的一些偏移组合将产生相同的操作。