如何调试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
相关产品推荐
相关产品推荐

