【发布时间】:2013-03-24 08:46:11
【问题描述】:
如何编写将标签引用的地址放入寄存器的指令?
【问题讨论】:
如何编写将标签引用的地址放入寄存器的指令?
【问题讨论】:
有四种方法,其中三种记录在Sourceware's Gnu Assembler manual。我猜标签是这样的,
target:
.long 0xfeadbeef
adr r0,targetadrl r0,targetldr r0,=targetsub r0,pc,#(.+8-target)前两个非常相似,生成sub r0,pc,#offset。 3rd 将 long 放入 literal pool 并通过 ldr r0,[pc,#offset2] 加载它,或者如果汇编器发现它可以使用 mov(通常是对齐的标签) ,例如 0x8000)。最后一个版本是手动计算的。
adr 和adrl 的区别在于直接操作数。它们以 2 的倍数旋转 8 位。因此,如果地址很远,您可能需要执行两条指令,这通常比 3rdldr 变体更快,后者通过 数据缓存获得完整的 32 位/em> 或 内存。
Thumb2 添加movw 和movt 的组合。例如,
label:
; data
...
movw r0, :lower16:label - .
movt r0, :upper16:label - .
这会将偏移量放入r0。它对 PC 相对值没那么有用,但对绝对值或直接加载常量很有用。
【讨论】:
ldr rx,=constant for,因为它通常用于循环初始化,通常对性能不重要,但代码密度可能很重要。 '手册'版本是为了解释,不是为了实际使用。