ARM 程序集 - 斐波那契实现:PUSH 和 POP 未按预期工作
ARM assembly - Fibonacci Implementation: PUSH and POP not working as expected
我写了这个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 个数字后使其 return 进入主程序。但是现在我需要解决一些问题。
当我的代码到达这一行时:
PUSH {R4, R2, LR}
它应该将值 R4、R2 和 LR 压入堆栈,此时它们是:1、0、LR。
然后代码进入我正在执行的 'Return' 子例程:
POP {R2, R3, PC}
所以此时 R2 应该加载值 1,R3 加载值 0,PC 加载值 LR 所以我 return 到这一行:
ADD R4, R2, R3
代码对 ADD 行执行 return 但是 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
说明。
我写了这个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 个数字后使其 return 进入主程序。但是现在我需要解决一些问题。
当我的代码到达这一行时:
PUSH {R4, R2, LR}
它应该将值 R4、R2 和 LR 压入堆栈,此时它们是:1、0、LR。 然后代码进入我正在执行的 'Return' 子例程:
POP {R2, R3, PC}
所以此时 R2 应该加载值 1,R3 加载值 0,PC 加载值 LR 所以我 return 到这一行:
ADD R4, R2, R3
代码对 ADD 行执行 return 但是 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
说明。