soc.c
void my_fun ( void )
{
}
sos.s
.thumb
ldr r2, my_fun_label
bx r2
my_fun_label: .word my_fun
сборка и разборка
arm-none-eabi-gcc -mthumb -O2 -c soc.c -o soc.o
arm-none-eabi-as sos.s -o sos.o
arm-none-eabi-ld -Ttext=0x1000 sos.o soc.o -o so.elf
arm-none-eabi-objdump -D so.elf
Disassembly of section .text:
00001000 <my_fun_label-0x4>:
1000: 4a00 ldr r2, [pc, #0] ; (1004 <my_fun_label>)
1002: 4710 bx r2
00001004 <my_fun_label>:
1004: 00001009 andeq r1, r0, r9
00001008 <my_fun>:
1008: 4770 bx lr
100a: 46c0 nop ; (mov r8, r8)
отлично работали
возможно захотитевыровняйте адрес так, чтобы у вас не было шансов на 50/50 шансов, что он сработает.
.thumb
ldr r2, my_fun_label
bx r2
nop
my_fun_label: .word my_fun
спасибо гну
arm-none-eabi-as sos.s -o sos.o
sos.s: Assembler messages:
sos.s:5: Error: invalid offset, target not word aligned (0x00000002)
sos.s:5: Error: invalid offset, value too big (0x00000002)
принудительное выравнивание
.thumb
ldr r2, my_fun_label
bx r2
nop
.align
my_fun_label: .word my_fun
что лучше
Disassembly of section .text:
00001000 <my_fun_label-0x8>:
1000: 4a01 ldr r2, [pc, #4] ; (1008 <my_fun_label>)
1002: 4710 bx r2
1004: 46c0 nop ; (mov r8, r8)
1006: 46c0 nop ; (mov r8, r8)
00001008 <my_fun_label>:
1008: 0000100d andeq r1, r0, sp
0000100c <my_fun>:
100c: 4770 bx lr
100e: 46c0 nop ; (mov r8, r8)
самоизменяющийся код - это еще одна история, в которой вам, возможно, придется использовать барьеры и / или иметь дело с кэшированием и т. д. ...