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

RISC-V实现阿克曼函数陷入死循环,无法输出正确结果求助

问题排查与修复

你的RISC-V汇编代码陷入无限循环的核心原因是参数初始化错误,同时存在一处冗余代码,以下是具体分析和修复方案:

1. 致命错误:main函数参数初始化逻辑错误

你在main函数中用以下代码传递阿克曼函数的参数:

addi a3, a3, 3
addi a4, a4, 4

RISC-V程序启动时,通用寄存器(如a3、a4)的初始值是未定义的,直接基于未知值做加法会导致传入ackermann的参数完全错误(比如n或m变成极大值),进而引发无限递归。

修复方式:从zero寄存器(固定值为0)初始化参数,确保传入的n=3、m=4是确定的:

addi a3, zero, 3  ; 初始化n为3
addi a4, zero, 4  ; 初始化m为4

2. 冗余代码(不影响功能但可优化)

在n_notzero分支中,调用ackermann后执行jal ra, return属于冗余操作:

jal ra, ackermann
jal ra, return   #return ackermann(n-1, 1)

当ackermann递归调用返回后,当前函数的栈帧还未恢复,直接跳转到return是正确的,但可以简化为让流程自然进入return(该冗余代码不会导致错误,仅影响代码简洁性)。

修复后的完整汇编代码

.globl main

.text

main:
    addi a3, zero, 3  ; 正确初始化n=3
    addi a4, zero, 4  ; 正确初始化m=4
    
    jal ra, ackermann
    
    addi a1, a0, 0
    addi a0, zero, 1 
    ecall
    addi a0, zero, 10
    ecall
    
ackermann:
    addi sp, sp, -16
    sw a4, 8(sp)        
    sw a3, 4(sp)
    sw ra, 0(sp)
    
    bne a3, zero, n_notzero #n!=0 opposite of n==0 query
    
    addi a0, a4, 1  #m+1
    
    jal ra, return#return m+1
    
n_notzero:
    bne a4, zero, m_notzero #m!=0
    
    addi a3, a3, -1
    addi a4, zero, 1
    jal ra, ackermann
    jal ra, return   #return ackermann(n-1, 1)
    
m_notzero:
    #return ackermann(n-1, ackermann(n,m-1))
    #ackermann(n,m-1)
    
    addi a4, a4, -1
    jal ra, ackermann
    
    add t0, a0, zero  #保存ackermann(n,m-1)的结果
    add a4, t0, zero    
    lw a3, 4(sp)    
    addi a3, a3, -1     #n-1
    jal ra, ackermann #调用ackermann(n-1, 结果)
    
    jal ra, return
    
return:
    lw ra, 0(sp)
    addi sp, sp, 16
    jalr zero, ra, 0

修复后运行代码,即可得到正确输出125。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 12:02:14