рука ассемблер: bx прыгнуть в никуда - PullRequest
0 голосов
/ 12 декабря 2018

Я пытаюсь написать код на ассемблере внутри C, а затем вызвать функцию C.Мой код выглядит следующим образом:C:

void my_fun(uint32_t *arg) {
   //sth
}

Ассемблер:

ldr r2, my_fun_label
bx r2
my_fun_label: .word my_fun 

Используя отладчик, я обнаружил, что регистр r2 содержит некоторое случайное значение вместо адресов my_fun.Так что ветка программы в никуда, и замерзает.Кто-нибудь может мне помочь?Я использую микроконтроллер ARM Cortex M4 nRF52.

Редактировать: Результаты

0003ea0a: my_fun: 

asm_test: 
0003ea26: ldr r2, [pc, #0] ;(0x3ea28 <asm_test+2>) 
0003ea28: bx r2 
0003ea2a: and.w r0, sp, r3

, но my_fun_label, кажется, указывает на 0x0dea0300

1 Ответ

0 голосов
/ 12 декабря 2018

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)

самоизменяющийся код - это еще одна история, в которой вам, возможно, придется использовать барьеры и / или иметь дело с кэшированием и т. д. ...

...