本文介绍了将标签地址获取到 ARM 上的寄存器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

How do I write an instruction which will have the address a label is referencing put into a register?

推荐答案

有四种方法,三种在 Sourceware 的 Gnu 汇编器手册.我猜标签是这样的,

There are four ways, three are documented at Sourceware's Gnu Assembler manual. I guess the label is something like,

 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.3 将 long 放入 literal pool 并通过 ldr r0,[pc,#offset2] 加载它,或者它可以使用 mov 如果汇编器发现它可以(通常是对齐的标签,如 0x8000).最后一个版本是手动计算的.

The first two are very similar and generate sub r0,pc,#offset. The 3 puts a long in a literal pool and loads this via ldr r0,[pc,#offset2] or it may use a mov if the assembler finds it can (usually an aligned label, like at 0x8000). The last version is to manually calculated it.

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

The difference between adr and adrl comes from immediate operands. They are 8bits rotated by a multiple of two. So if the address is far, you may need to perform two instructions, which will usually be faster than the 3 ldr variant which get a full 32-bits via the data cache or memory.

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

Thumb2 添加了 movwmovt 的组合.例如,

Thumb2 adds the combination movw and movt. For example,

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

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

This will put the offset in r0. It is not as useful for PC relative but useful for absolutes or direct loads of constants.

参见:关于常量的 ARM 博客

这篇关于将标签地址获取到 ARM 上的寄存器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-19 16:21