ARM 汇编中带 [] 和不带命令的区别

Leo*_*onz 2 assembly arm addressing-mode

我注意到在 ARM 程序集中,有 3 种类型(我知道,可能还有更多)加载/存储命令。到目前为止,我已经看到:

    STR R0, [R1, #4]

    STR R0, [R1], #4

    LDR R0, R1, #4
Run Code Online (Sandbox Code Playgroud)

这些只是我见过的命令的示例。注意最后一个命令是加载而不是存储,那是因为我还没有看到 STR R0、R1、#4,所以我不知道写那个会不会编译。

我知道 #4 表示将 R1 增加 4(可能),但是与上述命令中的 [] 有什么区别?

Dri*_*512 6

第一个是preindexed:在执行操作之前将偏移量添加到基数:

STR r0, [r1, #4]
Run Code Online (Sandbox Code Playgroud)

表示存储在地址 r1+0x4 处完成

请注意,存在预索引 + 回写。这个操作会做同样的store操作,只是基地址会更新为地址。所以最后R1 = R1 + 4

STR r0, [r1, #4]!
Run Code Online (Sandbox Code Playgroud)

另一个是后索引,这总是意味着回写:

STR r0, [r1], #4
Run Code Online (Sandbox Code Playgroud)

在这种情况下,存储操作使用地址 r1(无偏移),但基址寄存器更新为R1 = R1 + 0x4在存储之后。

对于某些指令,您可以使用作为寄存器的偏移量,有时还带有移位。例如:

STR r0, [r1, r2] ; Store at address r1 + r2
STR r0, [r1, r2 LSL #2] ; Store at address r1 + r2 x 4
Run Code Online (Sandbox Code Playgroud)

并非所有加载/存储指令都可以具有所有寻址模式。

  • 只是为了澄清,当使用预索引时,基址寄存器(例如“r1”)不会改变,除非调用写回指令。可以通过在预索引地址末尾添加“!”来完成写回,例如“STR r0,[r1,#4]!” (2认同)