看http://github.com/dwelch67/yagbat QEMU目录。
这里有一对夫妇从手臂调用手臂或拇指的例子
start_vector:
mov sp,#0x20000
;@ call an arm function from arm
bl notmain
;@ call a thumb function frm arm
ldr r0,=0xAABBAABB
bl hexstring_trampoline
;@ call a thumb function frm arm
ldr r0,=0x12341234
ldr r1,hexstring_addr
mov lr,pc
bx r1
;@ call a thumb function frm arm
ldr r0,=0x12312344
bl hexstring_trampoline
hang:
b hang
hexstring_trampoline:
ldr r1,hexstring_addr
bx r1
hexstring_addr: .word hexstring
如果你看看指令集,你会发现你需要使用BX或BLX于ARM和Thumb状态之间切换。 BLX并不像BX那样得到广泛的支持。
从定义的角度来看,程序计数器,PC是超前两个指令的指令的执行期间。对于拇指是4字节,对于手臂8字节。两种情况下的说明。为了模拟一个不能用来改变状态的BL,你需要加载带有返回地址的链接寄存器,并根据地址的ls位使用bx分支到函数改变状态。所以
mov lr,pc
bx r1
here:
mov lr,pc上面加载这里的地址:这是我们的返回地址,bx r1以独立状态的方式调用函数。 LR的地址LSbit表示方式返回,你需要经常使用BX返回
pre_thumb:
ldr pc,lr
thumb_capable:
bx lr
编译器分配BL指令调用函数,链接器填充其余的以后,如果太远远达不到,那么它需要链接器自己添加的蹦床功能。同样,如果你需要改变模式,bl会调用一个蹦床函数。我仿照上面的一个模拟,你可以看到它有点浪费,希望我对编译器的解释只是为BL分配空间使得更清晰,浪费将是总是计划模式更改,并且必须为代码中的大部分函数调用插入nops。
代码还包括呼叫从拇指汇编手臂:
.thumb
.thumb_func
.globl XPUT32
XPUT32:
push {lr}
;@ call an arm function from thumb asm
ldr r2,=PUT32
mov lr,pc
bx r2
pop {r2}
bx r2
大致相同,除了你不能弹出的拇指模式,LR,你可以弹出到PC,但我不认为切换模式,所以你不能使用它,你需要一个备用注册表。当然,你需要知道的调用约定知道注册就可以使用,或者你可以换另一套推动和弹出保存所有,但LR
push {r2,lr}
;@ call an arm function from thumb asm
ldr r2,=PUT32
mov lr,pc
bx r2
pop {r2}
mov lr,r2
pop {r2}
bx lr
拇指以拇指或手臂武装你只需要使用一个BL如果你能达到。 ldr pc,地址如果你不能。
其中是该编译器从? –
kernel.o :(。ARM.exidx + 0x0):未定义对'__aeabi_unwind_cpp_pr1'的引用 make:*** [kernel.elf] Error 1 –
你是在试图构建一个arm linux应用程序吗?或嵌入式(无操作系统)应用程序?如果一个linux应用程序那么你不需要启动代码,工具链应该为你做所有这些,你担心main()作为你的入口点。 –