使用spim测试MIPS位操作时输入变量打印异常问题排查
问题根源分析
你的代码核心问题是读取第二个输入时没有重新设置syscall的功能号,导致第二次syscall执行的是第一个输入值对应的系统调用,而非预期的“读整数”操作。
MIPS syscall的规则是:调用前必须把功能号存入$v0,执行完syscall后,$v0会被覆盖为返回值(比如读整数时返回输入的数值)。你的代码中:
- 第一次读整数:正确设置
li $v0, 5(功能5是读整数),执行syscall后$v0变成输入的第一个数。 - 第二次读整数:直接调用
syscall,此时$v0里是第一个输入的数值,这个数值会被当作syscall功能号执行,从而触发各种异常行为:- 输入5:
$v0=5,刚好对应“读整数”功能,所以正常工作。 - 输入2:
$v0=2,对应“打印浮点数”功能,此时$f12未初始化,输出0.00000000,且不会读取第二个输入。 - 输入7:
$v0=7,对应“读浮点数”功能,该功能会把结果存在浮点寄存器$f0而非$v0,你用move $t1, $v0拿到的还是第一个输入的7,看起来像是“忽略第二个数”。 - 输入8:
$v0=8,对应“读字符串”功能,需要$a0指向合法的缓冲区,但你的代码里$a0是垃圾值,导致访问非法内存,触发memory address out of bounds错误。
- 输入5:
修复方案
在读取第二个输入前,重新设置$v0=5即可:
# Capture first input, place in $t0 li $v0, 5 syscall move $t0, $v0 # Capture the second input, place in $t1 li $v0, 5 # 新增这一行,重新设置读整数的功能号 syscall move $t1, $v0
关于你尝试的其他方案的说明
你改用read float或read double后程序忽略输入,是因为浮点数的读取和存储需要使用浮点寄存器(如$f0、$f1),而非通用寄存器$v0,且不能用move指令传输浮点数,需要用mfc1(把浮点寄存器的值转到通用寄存器)或mtc1(反向)。但你的场景是处理整数位操作,完全不需要用浮点数输入,修复syscall功能号即可解决问题。
内容的提问来源于stack exchange,提问作者Collisteru
相关产品推荐
相关产品推荐

