为什么R4不会被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){ 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 08:44:27 浏览: 141
在这段汇编代码中,R4寄存器被用来存储func1的第二个参数arg2的值。在调用func2之后,R0寄存器存储了func2的返回值,但是没有保存R4寄存器的值。因此,在ADD指令中,R4的值丢失了,导致函数返回的值不正确。为了解决这个问题,可以将R4的值保存在另一个寄存器中,例如R5,然后在ADD指令中将R5的值加回到R0中。
相关问题
为什么R4不会被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){ 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 }
R4不会被保留是因为在func2函数中,只有r0被用来返回结果,其他寄存器的值都不会被使用。如果你想让R4被保留下来并在后续的代码中使用它,可以在func2函数中将R4作为第五个参数传递并在相应的位置使用它。
修改后的代码如下:
__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, int arg5){
MULS r0, r1, r0 ; r0 = arg1 * arg2
MULS r0, r2, r0 ; r0 = r0 * arg3
MULS r0, r3, r0 ; r0 = r0 * arg4
ADDS r0, r0, r4 ; r0 = r0 + arg5
BX lr ; return value in r0
}
在这个修改后的代码中,func2函数接受五个参数,其中第五个参数是R4的值。在函数中,我们将R4的值添加到计算结果中,并将结果存储在R0中,以便在func1函数中使用。
为什么调用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 }
在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函数中的调用点。
阅读全文