CREATOR RISC-V模拟器实现sin函数遇无限输出及参数传递错误
问题分析与修复方案
1. 无限输出循环的原因
你的退出系统调用参数写错了:RV32架构下,退出程序需要设置a7=93(系统调用号),a0存放退出码。当前代码打印完浮点数后,直接执行li a0,10再ecall,此时a7仍是之前的2(打印浮点数的调用号),导致程序重复执行打印操作,陷入无限循环。
2. 调用约定错误的原因
按照RV32IMFD的调用约定:
s0-s11属于被调用者保存寄存器,函数若要使用这些寄存器,必须先将原有值压栈保存,函数结束前恢复,否则会破坏调用者的寄存器状态。你的sin函数直接使用s0和s1,未做保存恢复操作,触发了模拟器的调用约定检查错误。- 函数参数传递不符合规范:
sin函数应通过浮点寄存器fa0接收输入参数,而非直接读取全局变量valueTest;返回值放在fa0的逻辑是正确的。
修复后的代码
.data pi: .float 3.14159 # π的近似值 valueTest: .float 6.28 # 测试值(范围[-2π, 2π]) .text main: # 加载测试值到fa0,作为sin函数的输入参数 la t0, valueTest flw fa0, 0(t0) # 调用sin函数 jal ra, sin # 打印浮点数结果(a7=2,结果已在fa0中) li a7, 2 ecall # 正确退出程序:a7=93是退出系统调用号,a0为退出码 li a0, 0 li a7, 93 ecall # sin函数:输入参数fa0(待计算正弦值的浮点数),返回值fa0(计算结果) sin: # 保存被调用者保存寄存器s0、s1到栈(因要使用它们) addi sp, sp, -8 sw s0, 0(sp) sw s1, 4(sp) # 加载π的值 la s0, pi flw fs0, 0(s0) # 注:此处为占位计算,真实sin需实现泰勒展开等近似算法 fmul.s fa0, fa0, fs0 # 恢复被调用者保存寄存器 lw s0, 0(sp) lw s1, 4(sp) addi sp, sp, 8 jr ra # 返回调用者
关键修复点说明
- 修正退出系统调用参数:设置
a7=93确保程序正常退出,终止无限循环。 - 遵守寄存器调用约定:
sin函数使用s0、s1前先压栈保存,结束后恢复,避免破坏调用者寄存器状态。 - 规范参数传递:通过
fa0传递输入参数给sin函数,符合RISC-V浮点函数调用规范。 - 注意:当前代码中的
fmul.s仅为占位逻辑,真实正弦函数需要实现泰勒级数展开(需先将输入值归一化到[-π/2, π/2]区间)或其他近似算法。
内容的提问来源于stack exchange,提问作者user20442513
相关产品推荐
相关产品推荐

