ARM 汇编中的偏移量是什么?它是如何工作的?

问题描述

我正在学习 ARM 汇编语言。我所做的是用c 编写一个程序并编译它以查看Assembly 文件。下面是这样一个程序的编译片段,它有这个 ldr r0,[pc,#28]在这里,我需要帮助来理解这个 PC 的东西。我知道这意味着程序计数器,但我无法理解指令的实际用途。

1000037c <main>:
1000037c:    b570         push  {r4,r5,r6,lr}
.
.
10000388:    f000 f812    bl    100003b0
1000038c:    4807         ldr   r0,#28]
1000038e:    626c         str   r4,[r5,#36]
.
.

在C程序中,它一定是一个整数(> 256)也许,我不完全理解这个概念。 提前致谢。

解决方法

您正在查看的是一条预索引加载指令,使用 pc 寄存器的值作为基地址。

任何时候您的代码需要将“大”立即数加载到寄存器中时,您很可能会看到类似这样的内容以及其下方某处的数据声明。您还没有在代码片段中显示它,但在程序集中向下滚动一点,您可能会看到如下内容:

.word 0x12345678

甚至可能是标签的价值

_some_label: ...
...
.word _some_label

只要 .word 值在内存中与 pc 当前执行的位置足够接近,您就可以使用相对偏移量加载数据。在您的示例中,应该在加载指令所在位置的偏移 32 处有一个数据字(根据 PC 相对寻址的 ARM ISA 添加 8)。

一般来说,当您手动编写程序集时,这种加载立即数的方法可能会很棘手(因为您需要跟踪指令所在位置的确切相对偏移量),但编译器可以非常可靠地做到这一点,这就是为什么您经常在编译器生成的程序集中看到这一点。

This question 也可以作为很好的参考,我强烈建议您查看一下。