Rx 和 [Rx] 之间的区别

Difference between Rx and [Rx]

LDR R0, R1    ; statement 1
LDR R0, [R1]  ; statement 2

两种说法有什么区别?

语句1中,R0中存放的是寄存器地址吗?

语句2中R1指向的4字节数据是否加载到R0中?

是的,ldr r0, [r1]从内存中加载 4 个字节,使用 R1 作为地址。

ldr 的第二个操作数必须是内存,使用某种寻址模式1,而不是裸寄存器。

LDR R0, R1 要么是语法错误,要么是 试图将 R1 用作符号名称 (与 ldr r0, foo 等任何其他字符串一样),而不是登记。如果您不厌其烦地尝试一下,您会看到类似 Error: internal_relocation (type: OFFSET_IMM) not fixed up(来自 GNU as)的错误消息。当您的源文件不包含该标签时,这与您为 ldr r0, foo 收到的错误消息相同。

(如果您的源代码中某处确实有一个 R1: 标签,此 ldr R0, R1 加载将引用它。再次反汇编,如果该标签在后面,您将得到 ldr r0, [pc, #4]还有 2 条指令。同样,与使用 foo 而不是 R1 作为符号名称完全相同。使用寄存器名称作为符号对于人类可读性来说是个坏主意,但如果您实际上会发生这种情况使用 GNU 汇编程序(来自 GNU binutils)执行此操作。 显示示例)

如果你想复制寄存器,使用mov r0, r1,一个不同于ldr的助记符(和机器代码操作码)。


脚注 1: 或者有 ldr 的伪指令形式,如 ldr r0, =0x1234 将常量放入寄存器中,并使用汇编程序选择的指令,或者在一些汇编程序总是从附近的“文字池”中加载与 PC 相关的内容。但是 asm 源代码中的那种 ldr 要么汇编成 ldr r0, [pc, #offset] ,要么汇编成一些根本不是 ldr 的指令。