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

RISC-V递归实现斐波那契数列错误排查:n=7输出异常

RISC-V递归斐波那契代码错误分析与修复

你的代码存在多处逻辑错误,导致输出始终为2,具体问题及修复方案如下:

错误点梳理

  • 终止条件返回值逻辑错误:斐波那契数列定义为fib(0)=0、fib(1)=1,但你的done块直接执行add x10, x10, x5,此时x5未针对终止场景做正确初始化(比如n=1时x5为1,x10为1,相加后得到2,这是输出2的直接原因)。
  • 栈操作完全混乱:
    1. 第一次递归返回后,你用ld x5,0(sp)取出原n值,随即把当前x10(fib(n-1)的结果)存到栈的0(sp)位置,直接覆盖了原n值,后续无法正确获取原n来计算n-2。
    2. 调用fib(n-2)后,ld x5,8(sp)取出的是ra寄存器的值,而非之前保存的fib(n-1)结果,导致相加逻辑完全错误。
    3. 栈的恢复操作(ld ra,0(sp)、addi sp,sp,16)放在done块内,会导致递归未完成就提前恢复栈并触发退出。
  • 系统调用位置错误:在done块内执行打印和退出系统调用,会让递归过程中就触发打印和退出,无法完成完整的递归计算流程。

修改后的代码

# 初始化n=7到x10(若运行环境x10初始非0,可改为li x10,7)
addi x10, x0, 7  
jal x1, fib     # 调用递归斐波那契函数
li a7, 1        # 触发打印系统调用
ecall
li a7, 10       # 触发程序退出系统调用
ecall

# 递归斐波那契函数,输入x10为n,返回x10为fib(n)
fib:
    # 终止条件:fib(0)=0
    beq x10, x0, fib0
    # 终止条件:fib(1)=1
    addi x5, x0, 1
    beq x10, x5, fib1

    # 栈空间分配:保存ra、原n值、fib(n-1)结果,共24字节
    addi sp, sp, -24
    sd ra, 16(sp)
    sd x10, 8(sp)

    # 计算fib(n-1)
    addi x10, x10, -1
    jal x1, fib
    sd x10, 0(sp)  # 将fib(n-1)结果存入栈

    # 计算fib(n-2)
    ld x10, 8(sp)  # 恢复原n值
    addi x10, x10, -2
    jal x1, fib

    # 计算fib(n) = fib(n-1) + fib(n-2)
    ld x5, 0(sp)   # 取出fib(n-1)结果
    add x10, x10, x5

    # 恢复栈与返回地址,返回上层调用
    ld ra, 16(sp)
    addi sp, sp, 24
    jalr x0, x1, 0

# fib(0)返回0
fib0:
    li x10, 0
    jalr x0, x1, 0

# fib(1)返回1
fib1:
    li x10, 1
    jalr x0, x1, 0

修改说明

  1. 拆分主程序与递归函数:将递归逻辑独立为fib函数,主程序仅负责初始化参数、调用函数、打印结果和退出,避免递归过程中触发系统调用打断流程。
  2. 明确终止条件返回:为fib(0)和fib(1)设置独立的返回分支,直接返回对应数值,符合斐波那契数列定义。
  3. 规范栈操作流程:栈中依次保存返回地址、原n值、fib(n-1)的结果,确保递归调用过程中数据不被覆盖,计算完成后正确恢复上下文再返回。
  4. 修正递归计算逻辑:先计算并保存fib(n-1)的结果,再恢复原n值计算fib(n-2),最后将两者相加得到fib(n)的结果返回。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 13:17:33