将标签地址获取到 ARM 上的寄存器?

Posted

技术标签:

【中文标题】将标签地址获取到 ARM 上的寄存器?【英文标题】:Getting an label address to a register on ARM? 【发布时间】:2013-03-24 08:46:11 【问题描述】:

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

【问题讨论】:

【参考方案1】:

有四种方法,其中三种记录在Sourceware's Gnu Assembler manual。我猜标签是这样的,

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

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

adradrl 的区别在于直接操作数。它们以 2 的倍数旋转 8 位。因此,如果地址很远,您可能需要执行两条指令,这通常比 3rdldr 变体更快,后者通过 数据缓存获得完整的 32 位/em> 或 内存

另见:Relocation in assembler


Thumb2 添加movwmovt 的组合。例如,

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

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

见:ARM blog on constants

【讨论】:

我应该注意,'pc-relative' 通常对于执行地址可能不是恒定的共享库和引导代码很有用。相对于 pc 的版本也将执行得更快一些,“标签”可以是跳转或向量表,以实现更快的调度,您希望根据值执行几件事情中的一件。这就是这篇文章的重点。对于常量,人们通常使用ldr rx,=constant for,因为它通常用于循环初始化,通常对性能不重要,但代码密度可能很重要。 '手册'版本是为了解释,不是为了实际使用。

以上是关于将标签地址获取到 ARM 上的寄存器?的主要内容,如果未能解决你的问题,请参考以下文章

部分ARM汇编指令解读

在 ARM Cortex A8 上的汇编中 XOR NEON 向量/寄存器的所有元素/通道(成对?)

004.ARM指令之LDR

通过绕行特定地址获取寄存器值[Windows上的x86程序集]

ARM pc寄存器并不总是当前指令的地址加4(Thumb状态)

嵌入式:ARM间接寻址变址寻址与多寄存器寻址