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

MIPS汇编实现期末成绩计算器运行异常问题求助

问题根因

你的程序连续输出多条成绩提示、运行逻辑异常,是以下几个明确的代码错误导致的:

  • move指令操作数顺序写反:MIPS中move 目的寄存器, 源寄存器,你两处赋值完全颠倒:
    1. 调分值校验通过后写的move $v0, $t1,是把初始值为0的t1覆盖了存用户输入的$v0,正确写法应为move $t1, $v0,把用户输入的调分值存入t1
    2. 原始成绩校验通过后写的move $v0, $t0,是把初始值为0的t0覆盖了存用户输入的$v0,正确写法应为move $t0, $v0,把用户输入的原始成绩存入t0
      这两个错误会导致你根本没拿到用户输入的有效值,t0/t1要么是初始0值要么是残留随机值,直接导致分数计算错误。
  • 分支跳转后缺少退出逻辑,代码顺序穿透执行:这是连续打印多条等级提示的直接原因。你用bge跳转到对应等级的打印标签后,打印逻辑执行完没有跳转到程序出口,CPU会按地址顺序继续执行后面所有等级的打印代码——比如跳转到grade_a_plus打印完A+,会直接往下跑grade_a、grade_b_plus等所有后续标签的打印逻辑,直到代码段结束。
  • 输入校验指令用错:成绩小于0的校验你用了bltzal(小于0则跳转并链接,会无条件把返回地址写入$ra寄存器),你这里只需要判断小于0就重输,不需要保存返回地址,用普通blt指令即可,用bltzal会乱改$ra导致后续跳转跑飞。
  • 分数判断链不完整,无合法退出路径:你只写了95分以上、90-94、85-89三个区间的判断,85分以下的B、C、D、F区间完全缺失;分数判断结束后写的jr $31完全无效,因为$ra已经被bltzal破坏,且你没有写程序退出的系统调用,执行流会乱跳。
  • 输出缺少换行:所有等级字符串后没有加换行打印,输出会挤在同一行。
修正后可运行代码
.data
STR_MESSAGE1: .asciiz "Enter the grade: "
STR_MESSAGE2: .asciiz "Enter the curve: "
GRADEAPLUS: .asciiz "You earned A+"
GRADEA: .asciiz "You earned A"
GRADEBPLUS: .asciiz "You earned B+"
GRADEB: .asciiz "You earned B"
GRADECPLUS: .asciiz "You earned C+"
GRADEC: .asciiz "You earned C"
GRADEDPLUS: .asciiz "You earned D+"
GRADED: .asciiz "You earned D"
GRADEF: .asciiz "You earned F"
NEW_LINE:    .asciiz "\n"

.text
.globl main

main:
    # 初始化阈值寄存器
    li     $t0, 0              # 存原始成绩
    li     $t1, 0              # 存调分值
    li     $t2, 100            # 成绩上限
    li     $t3, 2              # 调分下限
    li     $t4, 8              # 调分上限
    li     $t5, 0              # 存最终总分

curve_check:
    li    $v0, 4
    la    $a0, STR_MESSAGE2
    syscall
    li    $v0, 5
    syscall                    
    blt   $v0, $t3, curve_check
    bgt   $v0, $t4, curve_check
    move  $t1, $v0             # 修正:把合法调分值存入t1

grade_check:
    li     $v0, 4
    la     $a0, STR_MESSAGE1
    syscall
    li     $v0, 5
    syscall
    blt    $v0, $zero, grade_check  # 修正:用普通blt替换bltzal,不修改ra
    bgt    $v0, $t2, grade_check
    move   $t0, $v0            # 修正:把合法原始成绩存入t0

score_add:
    addu   $t5, $t0, $t1
    # 补全所有分数区间判断
    bge    $t5, 95, grade_a_plus
    bge    $t5, 90, grade_a
    bge    $t5, 85, grade_b_plus
    bge    $t5, 80, grade_b
    bge    $t5, 75, grade_c_plus
    bge    $t5, 70, grade_c
    bge    $t5, 65, grade_d_plus
    bge    $t5, 60, grade_d
    j      grade_f

# 每个等级打印完加换行,跳转到程序退出
grade_a_plus:
    li     $v0, 4
    la     $a0, GRADEAPLUS
    syscall
    jal    print_newline
    j      exit

grade_a:
    li     $v0, 4
    la     $a0, GRADEA
    syscall
    jal    print_newline
    j      exit

grade_b_plus:
    li     $v0, 4
    la     $a0, GRADEBPLUS
    syscall
    jal    print_newline
    j      exit

grade_b:
    li     $v0, 4
    la     $a0, GRADEB
    syscall
    jal    print_newline
    j      exit

grade_c_plus:
    li     $v0, 4
    la     $a0, GRADECPLUS
    syscall
    jal    print_newline
    j      exit

grade_c:
    li     $v0, 4
    la     $a0, GRADEC
    syscall
    jal    print_newline
    j      exit

grade_d_plus:
    li     $v0, 4
    la     $a0, GRADEDPLUS
    syscall
    jal    print_newline
    j      exit

grade_d:
    li     $v0, 4
    la     $a0, GRADED
    syscall
    jal    print_newline
    j      exit

grade_f:
    li     $v0, 4
    la     $a0, GRADEF
    syscall
    jal    print_newline
    j      exit

# 打印换行公共函数
print_newline:
    li     $v0, 4
    la     $a0, NEW_LINE
    syscall
    jr     $ra

# 程序退出逻辑
exit:
    li     $v0, 10
    syscall

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 15:51:42