Для bx
функции Thumb необходимо установить младший бит адреса. GNU as документация заявляет, как это работает, когда адрес генерируется из псевдо-инструкция adr
:
adr ‹register› ‹label›
Эта инструкция загрузит адрес метки в указанный регистр. [...]
Если метка является символом функции большого пальца, и взаимодействие большого пальца было разрешено с помощью опции
-mthumb-interwork
, то будет установлен нижний бит значения, хранящегося в регистре. Это позволяет следующей последовательности работать должным образом:adr r0, thumb_function
blx r0
Похоже, что все должно работать. Однако, глядя на некоторую разборку, кажется, что для некоторых адресов не установлен этот нижний бит.
Например, сборка и компоновка:
.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
С участием:
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
, я получаю:
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)
Следует отметить несколько моментов:
- В
table
, как и ожидалось, абсолютные адресаf1
,f2
иf3
нечетные. Итак, очевидно, что ассемблер и компоновщик знают, что эти три функции должны быть Thumb. - Для обратных ссылок, где псевдо-инструкция
adr
собирается доsubw
, смещение, как и ожидалось, нечетное. - Но для прямых ссылок, где псевдо-инструкция
adr
собирается вadd
, смещение будет четным.
Что мне не хватает?
.type f3, %function
ранее? - person Peter Cordes   schedule 29.11.2019