Вам нужно прочитать ARM ARM и / или знать, что набор инструкций - это все, обычно вы хотите сделать что-то вроде этого
asm:
bl cfun
c:
void cfun ( void )
{
}
Вы можете попробовать это сами. для gnu as и gcc это прекрасно работает, оно также должно работать нормально, если вы используете clang для получения кода c для объекта и gnu как для ассемблера. Не уверен, что вы используете.
Проблема с вышеперечисленным ограничена,
if ConditionPassed(cond) then
if L == 1 then
LR = address of the instruction after the branch instruction
PC = PC + (SignExtend_30(signed_immed_24) << 2)
зная, что инструкция bl устанавливает регистр связи на инструкцию после инструкции bl, то если вы читаете о регистре счетчика программ:
For an ARM instruction, the value read is the address of the instruction
plus 8 bytes. Bits [1:0] of this
value are always zero, because ARM instructions are always word-aligned.
так что если вы сделаете ваш ассм похожим на это:
mov lr,pc
ldr pc,=cfun
вы получите
d6008034: e1a0e00f mov lr, pc
d6008038: e51ff000 ldr pc, [pc, #-0] ; d6008040
...
d6008040: d60084c4 strle r8, [r0], -r4, asr #9
Ассемблер зарезервирует в памяти область, в пределах досягаемости ldr pc, инструкции (если возможно, иначе выдаст ошибку), где он поместит полный 32-битный адрес для инструкции. компоновщик позже заполнит этот адрес внешним адресом. Таким образом, вы можете достичь любого адреса в адресном пространстве.
Если вы не хотите играть в подобные игры на ассемблере и хотите управлять им, вы создаете место для сохранения адреса функции и загружаете его в компьютер самостоятельно:
mov lr,pc
ldr pc,cfun_addr
...
cfun_addr:
.word cfun
скомпилированы:
d6008034: e1a0e00f mov lr, pc
d6008038: e51ff000 ldr pc, [pc, #-0] ; d6008040 <cfun_addr>
...
d6008040 <cfun_addr>:
d6008040: d60084c4 strle r8, [r0], -r4, asr #9
Наконец, если вы хотите перейти в современный мир ARM, где ARM и thumb смешаны или могут быть (например, используйте bx lr вместо mov pc, lr), тогда вы захотите использовать bx
add lr,pc,#4
ldr r1,cfun_addr
bx r1
...
cfun_addr:
.word cfun
конечно, вам нужен еще один регистр, чтобы сделать это, и не забудьте нажать и открыть свой регистр ссылок и другой регистр до и после вашего звонка в C, если вы хотите сохранить их.