为什么前向引用 ADR 指令在 Thumb 代码中以偶数偏移进行汇编?

2024-05-27

To bx对于 Thumb 函数,需要设置地址的最低有效位。 GNU 作为文档states https://sourceware.org/binutils/docs/as/ARM-Opcodes.html当地址是从一个生成时这是如何工作的adr伪指令:

adr

该指令将标签的地址加载到指定的寄存器中。 [...]

If label是拇指功能符号,拇指互通已 通过启用-mthumb-interwork选项,然后是底部位 存储到寄存器中的值将被设置。这允许以下序列按预期工作:

adr r0,thumb_function

BLX R0

所以听起来事情应该会顺利进行。然而,看看一些反汇编,似乎某些地址确实如此not设置了底部位。

例如,组装和链接:

.syntax unified
.thumb

.align 2
table:
    .4byte f1
    .4byte f2
    .4byte f3

.align 2
.type f1, %function
.thumb_func
f1:
    adr r1, f1
    adr r2, f2
    adr r3, f3
    bx r1

.align 2
.type f2, %function
.thumb_func
f2:
    adr r1, f1
    adr r2, f2
    adr r3, f3
    bx r2

.align 2
.type f3, %function
.thumb_func
f3:
    adr r1, f1
    adr r2, f2
    adr r3, f3
    bx r3

With:

arm-none-eabi-as adr_test.s -mthumb -mthumb-interwork -o adr_test.o
arm-none-eabi-ld adr_test.o

并检查arm-none-eabi-objdump -D a.out, I get:

00008000 <table>:
    8000:   0000800d    .word   0x0000800d
    8004:   00008019    .word   0x00008019
    8008:   00008025    .word   0x00008025

0000800c <f1>:
    800c:   f2af 0103   subw    r1, pc, #3
    8010:   a201        add r2, pc, #4  ; (adr r2, 8018 <f2>)
    8012:   a304        add r3, pc, #16 ; (adr r3, 8024 <f3>)
    8014:   4708        bx  r1
    8016:   46c0        nop         ; (mov r8, r8)

00008018 <f2>:
    8018:   f2af 010f   subw    r1, pc, #15
    801c:   f2af 0207   subw    r2, pc, #7
    8020:   a300        add r3, pc, #0  ; (adr r3, 8024 <f3>)
    8022:   4710        bx  r2

00008024 <f3>:
    8024:   f2af 011b   subw    r1, pc, #27
    8028:   f2af 0213   subw    r2, pc, #19
    802c:   f2af 030b   subw    r3, pc, #11
    8030:   4718        bx  r3
    8032:   46c0        nop         ; (mov r8, r8)

有几点需要注意:

  1. In table,绝对地址f1, f2, and f3正如预期的那样,都是奇怪的。所以,很明显,汇编器和链接器知道这三个函数should是拇指。
  2. 对于向后引用,其中adr伪指令汇编成subw,正如预期的那样,偏移量是奇数。
  3. 但对于前向参考,其中adr伪指令汇编为add,偏移量是偶数。

我缺少什么?


您缺少的是 ARM 文档中的这一行ADR 伪指令 http://infocenter.arm.com/help/topic/com.arm.doc.dui0204j/Babcjaii.html:

如果您使用 ADR 生成 BX 或 BLX 指令的目标,并且目标包含 Thumb 指令,则您有责任设置地址的 Thumb 位(位 0)。

前向引用 ADR 指令使用 16 位 Thumb“ADDRd, pc, #imm“ADD 指令的形式。该指令的立即数范围为 0-1020,并且必须字对齐(即,用 8 位字段编码并乘以 4。)所使用的 PC 值也具有较低的值两个位设置为 0,因此无法生成奇数地址。

强制汇编器始终使用带有 ADR.W 的 32 位 Thumb 指令应该会导致它在使用函数标签时始终生成奇数地址,但我不知道您是否可以依赖这一点。最好只显式设置较低位。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么前向引用 ADR 指令在 Thumb 代码中以偶数偏移进行汇编? 的相关文章

随机推荐