6

如何编写将标签引用的地址放入寄存器的指令?

4

1 回答 1

9

有四种方法,Sourceware 的 Gnu Assembler 手册中记录了三种方法。我猜标签是这样的,

 target:
     .long 0xfeadbeef
  1. adr r0,target
  2. adrl r0,target
  3. ldr r0,=target
  4. sub r0,pc,#(.+8-target)

前两个非常相似,并且生成sub r0,pc,#offset. 第三个将long放入文字池中并通过加载它,ldr r0,[pc,#offset2]或者mov如果汇编器发现它可以使用它(通常是对齐的标签,如0x8000),它可能会使用它。最后一个版本是手动计算的。

adr和之间的区别adrl来自直接操作数。它们是由 2 的倍数旋转的 8 位。因此,如果地址很远,您可能需要执行两条指令,这通常比通过数据缓存内存获得完整 32 位的第 3 变体更快ldr

另请参阅:汇编程序中的重定位


Thumb2 添加组合movwmovt。例如,

label:
 ; data
...
movw    r0, :lower16:label - .
movt    r0, :upper16:label - . 

这会将偏移量放入r0. 它对 PC 相对没有用,但对绝对或直接加载常量很有用。

请参阅:关于常量的 ARM 博客

于 2013-04-02T22:03:42.760 回答