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

MIPS汇编使用beq指令时函数跳转异常的问题排查

MIPS中beq指令无法正确分支的问题排查与解决

问题根源

你的代码存在两个致命逻辑错误,直接导致beq分支完全失效:

  1. 字符值被地址覆盖:你先通过li $s4, 'a'把字符'a'的ASCII值加载到寄存器,但紧接着执行move $s4, $a0——$a0是存储输入字符串的缓冲区地址,这直接把之前的字符值覆盖成了内存地址,$s5、$s7也被同样改成了同一个地址。
  2. 比较对象错误:$s6存储的是输入字符串的缓冲区地址,你用beq $s6, $s4, choiceA比较的是两个内存地址(而非输入字符和目标字符)。因为$s4/$s5/$s7都是同一个地址,所以第一个beq永远成立,无论输入什么都会跳转到choiceA。

修复方案

1. 删掉错误的赋值指令

移除move $s4, $a0、move $s5, $a0、move $s7, $a0这三行,保留li $s4, 'a'这类正确的字符ASCII值赋值。

2. 正确读取输入的字符

用lb指令加载输入缓冲区的第一个字节(即用户输入的字符)到临时寄存器,再用这个寄存器和目标字符做比较。

3. 补充遗漏的syscall指令

你的choiceB和choiceC分支里漏了syscall,即使跳转成功也不会执行打印操作,必须补上。

修正后的完整代码

# 定义输入缓冲区(建议改名避免和字符串标签冲突)
.data
input_buf: .space 50
countMsg: .asciiz "Choice A selected\n"
lessThanMsg: .asciiz "Choice B selected\n"
divisibleMsg: .asciiz "Choice C selected\n"
choiceWhatMsg: .asciiz "Invalid choice\n"

.text
.globl main
main:
    # 读取字符串输入
    li $v0, 8
    la $a0, input_buf
    li $a1, 50
    syscall
    
    # 读取输入的第一个字符
    lb $t0, ($a0)

    # 加载目标字符的ASCII值
    li $s4, 'a'
    li $s5, 'b'
    li $s7, 'c'

    # 分支判断
    beq $t0, $s4, choiceA
    beq $t0, $s5, choiceB
    beq $t0, $s7, choiceC
    # 输入无效时跳转到choiceWhat
    j choiceWhat

    # 退出程序
    li $v0, 10
    syscall

choiceWhat:
    li $v0,4
    la $a0,choiceWhatMsg
    syscall
    j done

choiceA:
    li $v0,4
    la $a0,countMsg
    syscall
    j done

choiceB:
    li $v0,4
    la $a0,lessThanMsg
    syscall
    j done

choiceC:
    li $v0,4
    la $a0,divisibleMsg
    syscall
    j done

done:

额外注意事项

  • 原代码中缓冲区变量名choice和打印字符串标签重名,会导致编译错误,建议改为input_buf这类独特名称。
  • syscall 8读取字符串时会包含用户输入的换行符,如果需要处理空输入(仅回车),可以增加对换行符'\n'的判断。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 20:33:32