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

MIPS汇编华氏转摄氏数组转换器出错,求排查FtoC函数问题

MIPS汇编华氏转摄氏转换器错误修复

问题核心错误点

你遇到的输出异常(0.0 0.0 NaN NaN 0.0)是由三个关键错误导致的:

  • 错误加载浮点数数组元素:使用lw(整数加载指令)读取.float类型数组,会将浮点数的二进制编码当作整数解析,后续转成浮点数时必然出错。
  • 整数转浮点数未做类型转换:直接用mtc1将整数(如32、5、9)传入浮点寄存器,但未执行cvt.s.w转换,导致浮点寄存器中存储的是整数二进制而非正确的浮点数表示。
  • 不必要的浮点数转整数操作:转换后的摄氏温度是浮点数,却用cvt.w.s转成整数再存入.float数组,破坏了浮点数编码,后续读取时出现NaN或0。

修正后的完整代码

.data
List_F: .float 1.5, 0, -5, -12, 1
List_C: .float 0,0,0,0,0

size: .word 5

startString: .asciiz "Converting the following Fahrenheit to Celsius \n"
celsiusDisplay: .asciiz "\n\nTemperatures in Celsius \n"
newLine: .asciiz "\n"
.text
j main

FtoC:
add $sp, $sp, -4 # 分配栈空间
sw $ra, 0($sp)   # 保存返回地址

li $t0, 0        # 循环计数器i
lw $t1, size     # 加载数组长度

# 初始化转换所需的浮点数常量
li $t6, 32
mtc1 $t6, $f6
cvt.s.w $f6, $f6 # 将整数32转为浮点数32.0

li $t7, 5
mtc1 $t7, $f2
cvt.s.w $f2, $f2 # 整数5转为浮点数5.0

li $t8, 9
mtc1 $t8, $f3
cvt.s.w $f3, $f3 # 整数9转为浮点数9.0

div.s $f7, $f2, $f3 # 计算5/9的浮点数结果

For:
    beq $t0, $t1, endFor # 循环终止条件:i == size
    sll $t3, $t0, 2      # 计算数组元素偏移量(每个float占4字节)
    
    l.s $f0, List_F($t3) # 正确加载单精度浮点数元素
    sub.s $f0, $f0, $f6  # F - 32.0
    mul.s $f4, $f0, $f7  # (F-32)*5/9
    
    s.s $f4, List_C($t3) # 直接将浮点数结果存入目标数组
    
    add $t0, $t0, 1      # 计数器自增
    j For
endFor:
lw $ra, 0($sp)   # 恢复返回地址
add $sp, $sp, 4  # 释放栈空间
jr $ra           # 返回主函数

main:
li $t0, 0        # 循环计数器i
lw $t1, size     # 加载数组长度
la $a0, startString
jal displayStartString

forFahrenheit:
beq $t0, $t1, endFahrDisplay
sll $t3, $t0, 2
l.s $f12, List_F($t3) # 正确加载浮点数用于打印
jal displayFahrenheit
la $a0, newLine
jal displayNewLine
add $t0, $t0,1
j forFahrenheit

endFahrDisplay:

jal FtoC

la $a0, celsiusDisplay
jal displayCelsiusString
li $t0, 0 # 重置计数器

forCelsius:
beq $t0, $t1, endCelsiusDisplay
sll $t3, $t0, 2
l.s $f12, List_C($t3) # 正确加载转换后的浮点数
jal displayCelsius
add $t0, $t0,1
la $a0, newLine
jal displayNewLine
j forCelsius

endCelsiusDisplay:
la $a0, newLine
jal displayNewLine
jal endProgram

displayNewLine:
li $v0, 4
syscall
jr $ra

displayFahrenheit:
li $v0, 2
syscall
jr $ra

displayCelsius:
li $v0, 2      # 打印浮点数的系统调用
syscall
jr $ra

displayCelsiusString:
li $v0, 4
syscall
jr $ra

displayStartString:
li $v0, 4
syscall
jr $ra

endProgram:
li $v0, 10
syscall
jr $ra

修正细节说明

  1. 浮点数指令替换:将操作.float数组的lw/sw全部替换为l.s/s.s,确保正确处理单精度浮点数的二进制编码。
  2. 补全整数转浮点数步骤:所有mtc1传入整数后,添加cvt.s.w指令,将整数二进制转换为对应的单精度浮点数。
  3. 移除冗余类型转换:删除cvt.w.s和mfc1指令,直接用s.s将浮点数结果存入目标数组,保留完整的浮点数精度信息。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 14:36:04