为什么调用func2()时,func1()的LR被重写了__asm int func1(int arg1, int arg2){ MOVS r4, r1 ; r4 = arg2 ; 1st argument already in r0 MOVS r1, #4 ; 2nd argument for func2 MOVS r2, #5 ; 3rd argument for func2 MOVS r3, #6 ; 4th argument for func2 BL func2 ; call func2 ADDS r0, r0, r4 ; return value in r0 … }__asm int func2(int arg1, int arg2, int arg3, int arg4){ MULS r0, r1, r0 ; r0 = arg1 * arg2 MULS r0, r2, r0 ; r0 = r0 * arg3 MULS r0, r3, r0 ; r0 = r0 * arg4 BX lr ; return value in r0 }
时间: 2024-03-18 21:44:20 浏览: 65
在ARM汇编中,BL指令用于将当前函数的返回地址(即LR寄存器中的值)保存到堆栈上,并跳转到另一个函数。当func2函数返回时,它会使用BX LR指令将控制权返回到func1函数中的调用点,这个返回地址被恢复到LR寄存器中。然而,在func2中没有使用BL指令调用其他函数,因此LR寄存器中的值不会被恢复到func1中的值。
因此,在func2函数中,当使用BX LR返回时,LR寄存器中的值被设置为func2函数中的返回地址,而不是func1函数中的返回地址。这会导致在func1函数中使用BX LR返回时,控制权不会返回到func1函数中的调用点,而是返回到func2函数中,这可能会导致意外的行为或错误。
为了解决这个问题,可以在func2函数中使用POP指令从堆栈中恢复LR寄存器的值,以便正确返回到func1函数中的调用点。修改后的代码如下所示:
__asm int func1(int arg1, int arg2){
MOVS r4, r1 ; r4 = arg2 ; 1st argument already in r0
MOVS r1, #4 ; 2nd argument for func2
MOVS r2, #5 ; 3rd argument for func2
MOVS r3, #6 ; 4th argument for func2
BL func2 ; call func2
ADDS r0, r0, r4 ; return value in r0 …
}
__asm int func2(int arg1, int arg2, int arg3, int arg4){
PUSH {lr} ; save LR
MULS r0, r1, r0 ; r0 = arg1 * arg2
MULS r0, r2, r0 ; r0 = r0 * arg3
MULS r0, r3, r0 ; r0 = r0 * arg4
POP {pc} ; restore LR and return
}
在这个修改后的代码中,我们在func2函数中使用了PUSH指令将LR寄存器的值保存到堆栈中,并在函数末尾使用POP指令恢复LR寄存器的值。这样,当func2函数返回时,LR寄存器中的值被恢复到func1函数中的值,控制权正确地返回到func1函数中的调用点。
阅读全文