我已经编写了这个 ARM 汇编代码。 它应该将斐波那契数列放在 R4 寄存器中。 我正在尝试在以下环境中实现此 C 代码:
int fibbonacci(int n) {
if(n == 0){
return 0;
} else if(n == 1) {
return 1;
} else {
return (fibbonacci(n-1) + fibbonacci(n-2));
}
}
这是汇编代码:
AREA |.text|, CODE, READONLY
EXPORT Fib
Fib
;R0(n) - store the first n numbers in the Fibonacci sequence
;R1 - address of the first element in the array to store the Fibonacci sequence
MOV R4, #0
MOV R5, #0
MOV R6, #1
FiboR
CMP R0, #1
PUSHEQ {R5, R6, LR}
BEQ Return
SUBS R0, R0, #1
BL FiboR
ADD R4, R2, R3
PUSH {R4, R2, LR}
Return
POP {R2, R3, PC}
ALIGN
END
到目前为止,它的行为与发布的 C 代码并不完全一样,因为我需要继续处理它并让它在打印前 5 个数字后返回 main。但是现在我需要解决一些问题。
当我的代码到达这一行时:
PUSH {R4, R2, LR}
它应该将值 R4、R2 和 LR 压入堆栈,此时它们是:1、0、LR。 然后代码进入我正在执行此操作的“Return”子例程:
POP {R2, R3, PC}
所以此时 R2 应该加载值 1,R3 加载值 0 PC 加载值 LR 所以我返回到这一行:
ADD R4, R2, R3
代码确实返回到 ADD 行,但是 R2 的值并没有像我预期的那样加载值 1。我的代码在无限循环中停留在这里,我一直将 {1, 0, LR} 压入堆栈,但是当我尝试将这些值弹出到 R2、R3 和 PC 时,显然它们没有像我期望的那样弹出值 1 不会进入 R2,R2 将永远保持其值 0。
你能帮我看看我错过了什么吗?感谢阅读!
编辑: 更改了行: 推 {R4, R2, LR}
到: 推 {R3, R4, LR}
现在可以了。有关详细信息,请参阅已接受的答案。
最佳答案
所有在寄存器列表上操作的指令总是按寄存器编号的升序压入、弹出、加载、存储...寄存器。所以即使写了{R4, R2, LR}
,实际推送的是{R2, R4, LR}
。如果您想要不同的顺序,则需要单独的 PUSH
指令。
关于recursion - ARM 程序集 - 斐波那契实现 : PUSH and POP not working as expected,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67772367/