MIPS汇编算术程序重复输出问题排查与输入校验实现
问题根因
两个问题直接导致你遇到的异常:
- 分支退出逻辑缺失:三个运算分支末尾只写了
li $v0,10加载程序退出的系统调用号,漏写了syscall指令触发实际的系统调用,程序执行到这行不会终止,会顺着内存地址顺序继续执行后面的代码段:- 输入3选乘法时程序正常,是因为乘法分支是代码里最后一个可执行段,后面无其他逻辑,不会触发重复输出
- 输入2选减法时,减法逻辑执行完后会顺序落到后面的乘法分支继续执行,因此累计输出2次结果
- 输入1选加法时,加法逻辑执行完后会顺序落到减法、乘法分支继续执行,因此累计输出3次结果
- 没有输入合法性校验:用户输入1-3范围外的数值时,程序不会做任何拦截,会直接落到加法分支执行,不符合交互预期。
修复方法
- 每个运算分支执行完、加载退出系统调用号后,补上
syscall指令,确保运算完成后直接终止程序 - 增加输入范围判断:用户输入值小于1或大于3时,打印错误提示后跳回菜单重新读取输入,直到拿到合法选项再进入对应运算分支
- 修正整数打印的指令写法:原来用
la $a0, ($t6)传整数值属于不规范写法,改用move $a0, $t6即可,避免部分汇编器运行报错。
修正后的完整可运行代码如下:
.data prompt1: .asciiz "Enter the first number: " prompt2: .asciiz "Enter the second number: " menu: .asciiz "Enter the number associated with the operation you want performed: 1 => add, 2 => subtract or 3 => multiply: " resultText: .asciiz "Your final result is: " invalidTip: .asciiz "Invalid input! Please enter a number between 1 and 3.\n" .text .globl main main: # 预存选项常量到寄存器 li $t3, 1 li $t4, 2 li $t5, 3 # 读取第一个数字 li $v0, 4 la $a0, prompt1 syscall li $v0, 5 syscall move $t0, $v0 # 读取第二个数字 li $v0, 4 la $a0, prompt2 syscall li $v0, 5 syscall move $t1, $v0 # 打印菜单、读取操作选项的入口,非法输入时会跳回这里 menu_input: li $v0, 4 la $a0, menu syscall li $v0, 5 syscall move $t2, $v0 # 输入范围校验 blt $t2, $t3, input_invalid bgt $t2, $t5, input_invalid # 合法选项分支跳转 beq $t2,$t3,addProcess beq $t2,$t4,subtractProcess beq $t2,$t5,multiplyProcess input_invalid: li $v0, 4 la $a0, invalidTip syscall j menu_input addProcess: add $t6,$t0,$t1 li $v0,4 la $a0,resultText syscall li $v0,1 move $a0, $t6 syscall li $v0,10 syscall # 补全退出系统调用 subtractProcess: sub $t6,$t0,$t1 li $v0,4 la $a0,resultText syscall li $v0,1 move $a0, $t6 syscall li $v0,10 syscall # 补全退出系统调用 multiplyProcess: mul $t6,$t0,$t1 li $v0,4 la $a0,resultText syscall li $v0,1 move $a0, $t6 syscall li $v0,10 syscall # 补全退出系统调用
内容的提问来源于stack exchange,提问作者Szarlotka
相关产品推荐
相关产品推荐

