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

如何调试RISC-V汇编编写的阶乘函数的无限循环报错问题

RISC-V阶乘代码错误排查与修正

核心错误点

  • 参数读取错误:main函数中已经把待计算的n值加载到a0寄存器作为函数入参,但factorial函数错误读取了存放n内存地址的t0寄存器,循环初始值是随机内存地址而非预期的数值8,大概率触发无限循环。
  • 循环步长错误:注释标注每次将循环变量减1,但代码中给s3赋值为4,每次执行减法操作实际是减4,若初始值不是4的倍数永远无法等于0,直接触发无限循环;即使是4的倍数,阶乘计算逻辑也完全错误。
  • 返回值不符合调用约定:RISC-V函数要求返回值存放在a0寄存器,你计算得到的阶乘结果存在s1中,未赋值给a0,函数返回后无法拿到正确结果。
  • 指令格式不规范:部分指令操作数之间缺少逗号,不符合标准汇编语法,部分汇编器可能无法识别,比如addi sp sp -16应写为addi sp, sp, -16。

修正后的完整代码

.globl factorial

.data
n: .word 8

.text
main:
    la t0, n  # t0存放n的内存地址
    lw a0, 0(t0) # a0存放待计算的n值,作为factorial的入参
    jal ra, factorial

    addi a1, a0, 0
    addi a0, x0, 1
    ecall # Print Result

    addi a1, x0, '\n'
    addi a0, x0, 11
    ecall # Print newline

    addi a0, x0, 10
    ecall # Exit

factorial:
    addi sp, sp, -16
    sw s0, 0(sp)  # s0作为循环变量i,初始值为n
    sw s1, 4(sp)  # s1存放累计的阶乘结果
    sw s2, 8(sp)
    sw s3, 12(sp)
    addi s1, x0, 1
    add s0, x0, a0 # 从入参a0读取n的数值
    addi s3, x0, 1 # 步长改为1,每次循环减1
loop: 
    beq s0, x0, exit
    mul s1, s1, s0
    sub s0, s0, s3
    j loop
exit:
    add a0, x0, s1 # 把阶乘结果赋值给返回寄存器a0
    lw s0, 0(sp)
    lw s1, 4(sp)
    lw s2, 8(sp)
    lw s3, 12(sp)
    addi sp, sp, 16
    ret

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 23:24:00