实现华氏转摄氏温度的MIPS汇编程序出现SPIM语法错误求助
问题排查与解决
语法错误原因
SPIM模拟器不支持ldc1指令直接加载立即数形式的浮点数(比如32.0),必须将浮点数常量定义在.data段中,通过标签引用加载。
代码修正步骤
1. 补充.data段的浮点数常量
在.data段末尾添加转换需要的浮点常量:
thirty_two: .float 32.0 # 对应32.0 nine: .float 9.0 # 对应9.0 five: .float 5.0 # 对应5.0,用于摄氏温度转换公式
2. 修正ldc1指令的用法
将过程中直接加载立即数的ldc1替换为从.data段加载单精度浮点数的l.s指令,比如:
# 原错误写法 ldc1 $f2, 32.0 # 修正后 l.s $f2, thirty_two
3. 修复转换过程的逻辑错误
原convertToFahrenheit过程存在多处逻辑问题:
- 未正确接收输入的华氏温度(main中把整数存在
$t0,但未传入浮点寄存器) - 初始的
sub.s $f0, $f12, $f0无意义(寄存器未初始化) - 转换公式错误(最后乘法用了9,正确公式是
(F-32)*5/9)
修正main中的传参代码
在调用转换过程前,把读取到的整数温度转为单精度浮点数,传入$f12作为过程参数:
# 把整数F转成单精度浮点数放到$f12 mtc1 $t0, $f12 cvt.s.w $f12, $f12
修正转换过程代码
# Conversion procedure convertToFahrenheit: # 公式:C = (F - 32) * 5 / 9 l.s $f2, thirty_two sub.s $f0, $f12, $f2 # F - 32 l.s $f2, five mul.s $f0, $f0, $f2 # (F-32)*5 l.s $f2, nine div.s $f0, $f0, $f2 # 除以9得到摄氏温度 jr $ra
4. 完整修正后的代码
.data prompt: .asciiz "Enter temperature in Fahrenheit: " result: .asciiz "The temperature in Celsius is: " prompt2: .asciiz "Convert another temperature? (y/n): " newline: .asciiz "\n" thirty_two: .float 32.0 nine: .float 9.0 five: .float 5.0 .text .globl main .ent main main: # Print prompt and read Fahrenheit temperature li $v0, 4 la $a0, prompt syscall li $v0, 5 syscall move $t0, $v0 # Save Fahrenheit temperature in $t0 # 将整数转换为单精度浮点数,传入$f12作为过程参数 mtc1 $t0, $f12 cvt.s.w $f12, $f12 # Call conversion procedure jal convertToFahrenheit # Print the Celsius temperature li $v0, 4 la $a0, result syscall li $v0, 2 mov.s $f12, $f0 # Move Celsius temperature to $f12 syscall # Ask if user wants another conversion li $v0, 4 la $a0, prompt2 syscall li $v0, 12 syscall move $t1, $v0 # Save user's input in $t1 # Check if input is 'y' li $t2, 'y' bne $t1, $t2, exit # Exit program if input is not 'y' # Print newline li $v0, 4 la $a0, newline syscall j main # Start another iteration of the program exit: # Program is finished running li $v0, 10 syscall .end main # Conversion procedure convertToFahrenheit: l.s $f2, thirty_two sub.s $f0, $f12, $f2 l.s $f2, five mul.s $f0, $f0, $f2 l.s $f2, nine div.s $f0, $f0, $f2 jr $ra
其他说明
l.s是SPIM加载单精度浮点数的标准指令,适配.float类型的常量,比ldc1更适合当前场景- 因为原代码读取的是整数温度,必须先转为浮点数才能进行浮点运算,否则会出现运算错误
内容的提问来源于stack exchange,提问作者Emiliano Martinez
相关产品推荐
相关产品推荐

