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)
有几点需要注意:
- In
table
,绝对地址f1
, f2
, and f3
正如预期的那样,都是奇怪的。所以,很明显,汇编器和链接器知道这三个函数should是拇指。
- 对于向后引用,其中
adr
伪指令汇编成subw
,正如预期的那样,偏移量是奇数。
- 但对于前向参考,其中
adr
伪指令汇编为add
,偏移量是偶数。
我缺少什么?