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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 02:57:16