有四种方法,其中三种方法记录在Sourceware的Gnu Assembler手册中。我想标签是这样的,
target:
.long 0xfeadbeef
Run Code Online (Sandbox Code Playgroud)
adr r0,targetadrl r0,targetldr r0,=targetsub r0,pc,#(.+8-target)前两个非常相似并生成sub r0,pc,#offset。的3 个放长在一个文字池和负载这通过ldr r0,[pc,#offset2]或者它可以使用一个mov,如果汇编程序找到它可以(通常是对齐的标签,如在为0x8000)。最后一个版本是手动计算它。
adr和之间的区别adrl来自立即操作数。它们是8 位旋转的2的倍数。因此,如果地址很远,则可能需要执行两条指令,这通常会比通过数据高速缓存或内存获得完整32位的第三种 ldr变体更快。
另请参阅:汇编程序中的重定位
Thumb2添加了movw和的组合movt。例如,
label:
; data
...
movw r0, :lower16:label - .
movt r0, :upper16:label - .
Run Code Online (Sandbox Code Playgroud)
这会将偏移量放入r0。它对PC相对而言没有用,但对绝对值或常数直接加载有用。
请参阅:有关常数的ARM博客