ST意法半导体
直播中

cherry1989

12年用户 940经验值
擅长:嵌入式技术
私信 关注
[问答]

PUSH和POP未按预期工作怎么解决?

编写了这个 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。但是现在我需要修复一些东西。
当我的代码到达这一行时:
推 {R4, R2, LR}
它应该将值 R4、R2 和 LR 压入堆栈,此时它们是:1、0、LR。
然后代码进入我正在执行此操作的“返回”子例程:
POP {R2, R3, PC}
所以此时 R2 应该加载值 1,R3 加载值 0,PC 加载值 LR,所以我返回到这一行:
添加 R4、R2、R3
代码确实返回到 ADD 行,但是 R2 的值没有像我预期的那样加载值 1。我的代码在无限循环中停留在这里,我一直将 {1, 0, LR} 压入堆栈,但是当我尝试将这些值弹出到 R2、R3 和 PC 时,显然它们没有像我期望的那样弹出值 1 不会进入 R2,R2 将永远保持其值 0。
你能帮我看看我在这里错过了什么吗?感谢您的阅读!







回帖(1)

仇国林

2023-1-4 10:13:49
处理器并不像您想象的那样工作,但它按照其规范工作:

由于它是 PUSH ,你没有按升序排列的寄存器,你应该已经看到堆栈上值的“不正确”(或意外)顺序。
是的,汇编程序可能已经警告过。也许有,但也许没有;现在的汇编器主要用作编译器的后端,编译器应该生成合理的代码。你使用什么工具链?
举报

更多回帖

发帖
×
20
完善资料,
赚取积分