You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AVR汇编递归斐波那契函数实现结果异常求助

排查AVR汇编实现递归斐波那契的异常问题

首先明确:斐波那契数列的递归逻辑是 f(0)=0, f(1)=1, f(n)=f(n-1)+f(n-2),n=10的正确结果是55,你遇到的0、20、60这类异常输出,大概率是栈管理、寄存器保存/恢复、递归终止条件或求和逻辑出了问题。结合你给出的代码片段,我整理几个关键排查和修复方向:

1. 寄存器的保存与恢复必须严谨

AVR汇编里递归调用时,非调用者保存的寄存器(比如你用到的r18、r24)必须先压栈,否则下一层递归会直接覆盖这些寄存器的值,导致上一层的计算结果完全丢失。

看你当前的代码片段,recur函数入口没有做寄存器保存操作,这是典型的错误点。修复示例:

recur:
    push r18       ; 先把当前用到的寄存器压栈保存
    push r24
    push r2        ; 假设r2是传入的n参数,也要保存
    ; --- 你的递归逻辑代码开始 ---
    ; ...
    ; --- 你的递归逻辑代码结束 ---
    pop r2         ; 退出前按逆序弹出恢复寄存器
    pop r24
    pop r18
    ret

2. 递归终止条件必须明确

如果recur函数没有正确处理n=0和n=1的终止情况,会导致递归逻辑混乱,要么无限递归,要么基数计算错误。你需要在函数开头就判断这两个条件:

recur:
    push r18
    push r24
    push r2

    cpi r2, 0      ; 判断n是否为0
    breq return0
    cpi r2, 1      ; 判断n是否为1
    breq return1

    ; --- 处理n>=2的递归逻辑 ---
    ; ...

return0:
    clr r18        ; f(0)=0
    rjmp end_recur
return1:
    ldi r18, 1     ; f(1)=1
end_recur:
    pop r2
    pop r24
    pop r18
    ret

3. 递归求和的栈管理不能出错

计算f(n-1)+f(n-2)时,你需要先保存f(n-1)的结果,再去计算f(n-2),否则后者会覆盖前者的值。常见错误是没把f(n-1)压栈保存,直接用寄存器承接导致丢失。

完整的求和逻辑示例(假设r2是传入的n,r18是返回值):

recur:
    push r18
    push r24
    push r2

    cpi r2, 0
    breq return0
    cpi r2, 1
    breq return1

    ; 计算f(n-1)
    dec r2
    call recur
    mov r24, r18   ; 把f(n-1)暂存到r24

    ; 计算f(n-2)
    dec r2         ; 此时r2已经是n-2
    call recur
    add r18, r24   ; 求和:f(n-1)+f(n-2)

    rjmp end_recur

return0:
    clr r18
    rjmp end_recur
return1:
    ldi r18, 1
end_recur:
    pop r2
    pop r24
    pop r18
    ret

4. 额外检查:数据溢出与指令正确性

虽然f(10)=55远小于8位寄存器的最大值255,但如果你的加法指令用错(比如误用adc带进位加法却没处理进位),也可能导致结果异常。另外要确认参数传递的寄存器是否正确,比如你是不是把n存在了其他寄存器,却在代码里错误地操作了r2?

最后建议你用AVR调试工具单步执行,观察每一步的寄存器值和栈内容,重点看递归终止时的返回值,以及求和步骤中两个子结果是否正确相加。

内容的提问来源于stack exchange,提问作者Kai

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:52:48