MIPS汇编代码加减运算异常求助:输入+得差、-得积
问题根源:MIPS跳转指令的延迟槽特性
你的代码出现的问题完全符合MIPS架构中跳转指令(j)的延迟槽特性:MIPS的j指令会先执行其后面的第一条指令(延迟槽指令),再跳转到目标地址。
看你的代码结构:
Add: add $s4, $s0, $s1 j Print Subtract: sub $s4, $s0, $s1 j Print Multiply: mul $s4, $s0, $s1 j Print Divide: divu $s0, $s1 mflo $s4 j Print
当执行Add标签的代码时:
- 执行
add计算两数之和,存入s4 - 执行
j Print,此时会先执行延迟槽内的下一条指令——Subtract标签下的sub,把s4覆盖成两数之差 - 才跳转到
Print打印结果,所以你看到的是差值
同理,执行Subtract时:
sub计算差值存入s4j Print的延迟槽执行Multiply下的mul,把s4覆盖成乘积- 跳转打印,得到乘积
而乘、除运算正常的原因是:
Multiply的j Print延迟槽执行Divide下的divu,该指令仅修改HI/LO寄存器,不会改变s4的乘积值Divide的j Print延迟槽执行Print标签下的li $v0,4,也不会修改s4的商值
修复方案
有两种简单的修复方式:
方式1:添加空操作指令(nop)填充延迟槽
在每个j Print后面添加nop,占据延迟槽,避免执行下一个运算的指令:
Add: add $s4, $s0, $s1 j Print nop Subtract: sub $s4, $s0, $s1 j Print nop Multiply: mul $s4, $s0, $s1 j Print nop Divide: divu $s0, $s1 mflo $s4 j Print nop
方式2:利用延迟槽优化指令顺序
将j Print移到运算指令前面,让运算指令作为延迟槽执行(这是MIPS延迟跳转的标准用法):
Add: j Print add $s4, $s0, $s1 Subtract: j Print sub $s4, $s0, $s1 Multiply: j Print mul $s4, $s0, $s1 Divide: divu $s0, $s1 j Print mflo $s4
内容的提问来源于stack exchange,提问作者welcomedandroid
相关产品推荐
相关产品推荐

