我正在为UNI做一个项目并遇到问题.我们正在学习如何在调用子程序时将寄存器推送到堆栈.我需要编写一个子程序,将十进制数0-15转换为相应的十六进制ASCII码,并保留除r0之外的所有寄存器的值,其中应存储结果.我有一个ASCII码表,基本上只需要将数字*4添加到ASCII表的起始地址,然后将值存回r0.我得到了正确的结果,但子程序循环.它不断从"ldmfd"命令跳到"sub".知道为什么吗?
main:
adr r0,num
adr r1,ascii
ldr r2,[r0]
bl sub
sub: stmfd sp!,{r1-r2,lr}
ldr r0,[r1,r2,LSL #2]
ldmfd sp!,{r1-r2,pc}
/* variables here */
num: .word 15
ascii: .word 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x41,0x42,0x43,0x44,0x45,0x46
/* end variables */
Run Code Online (Sandbox Code Playgroud)
请注意,您已将子例程直接放在调用它的指令之后:
bl sub
sub: stmfd sp!,{r1-r2,lr}
ldr r0,[r1,r2,LSL #2]
ldmfd sp!,{r1-r2,pc}
Run Code Online (Sandbox Code Playgroud)
那么当你从第一次通话回来时会发生什么sub
?它将返回到后面的指令bl
,即stmfd sp!,{r1-r2,lr}
.因此子程序有效地返回到它自身的开头.它将继续这样做,因为没有额外的隐式或显式写入lr
.
您的代码有两个问题。