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

MIPS汇编罗马数字解码器调试求助:地址越界与死循环问题

MIPS罗马数字解码器代码问题分析与解决思路

第一版代码:地址超出范围错误

问题现象

运行时触发“地址超出范围”错误,且无法正确返回解码结果。

错误原因

  1. 循环终止条件错误:仅判断下一个字符是否为\0,未处理当前字符为\0的情况。当索引指向字符串结束符\0时,程序仍会继续循环,越界访问内存区域,触发地址错误。
  2. 结果未存入返回寄存器:exit标签处未将计算结果$t0移动到返回寄存器$v0,导致main函数无法获取正确解码值。
  3. 字符遗漏处理:当处理最后一个字符时,因下一个字符是\0,程序直接跳转到exit,导致最后一个字符未被解码累加。

解决思路

  1. 修改循环终止逻辑:先检查当前字符是否为\0,若是则立即退出循环,避免越界访问。
  2. 在exit标签处添加move $v0, $t0,将结果存入返回寄存器$v0。
  3. 调整处理顺序:先获取当前字符并判断是否终止,再根据下一个字符的值决定加减操作,确保所有字符都被处理。

修正后的核心循环示例:

roman:
    li $t0, 0          # 初始化结果
    move $t1, $a0      # 保存输入字符串指针

roman_decoder:
    lb $t2, 0($t1)     # 加载当前字符
    beqz $t2, exit     # 当前字符为\0,退出循环

    lb $t3, 1($t1)     # 加载下一个字符
    move $a0, $t2
    jal romdigit       # 解码当前字符
    move $t4, $v0      # 保存当前字符的值

    beqz $t3, add_digit # 下一个字符为\0,直接累加当前值

    move $a0, $t3
    jal romdigit       # 解码下一个字符
    bgt $v0, $t4, subtract_digit # 下一个值更大,执行减法

add_digit:
    add $t0, $t0, $t4
    addi $t1, $t1, 1
    j roman_decoder

subtract_digit:
    sub $t0, $t0, $t4
    addi $t1, $t1, 2   # 跳过下一个字符,后续不再处理
    j roman_decoder

exit:
    move $v0, $t0
    jr $ra

第二版代码:程序无法终止

问题现象

程序陷入循环无法终止,无法回到main函数结束执行。

错误原因

  1. 返回地址寄存器未保存:roman函数调用romdigit时,jal romdigit会覆盖$ra寄存器的值(原本存储main函数的返回地址)。当执行exit标签处的jr $ra时,会跳回romdigit调用后的指令,而非main函数,形成死循环。
  2. 解码逻辑冗余:采用“当前值与前一个值比较”的方式,虽部分场景结果正确,但不符合罗马数字“当前值小于下一个值则减”的常规解码逻辑,易引发理解偏差和潜在错误。

解决思路

  1. 保存与恢复返回地址:在roman函数入口处,将$ra保存到栈中,调用romdigit后再恢复$ra,确保能正确返回main函数。MIPS栈操作示例:
    roman:
        addi $sp, $sp, -4  # 分配栈空间
        sw $ra, 0($sp)     # 保存$ra到栈
        # ... 原有逻辑 ...
    exit:
        move $v0, $t2
        lw $ra, 0($sp)     # 恢复$ra
        addi $sp, $sp, 4   # 释放栈空间
        jr $ra
    
  2. 调整解码逻辑:改为常规的“当前值与下一个值比较”的方式,逻辑更清晰,便于维护。例如:遍历字符串时,先获取当前字符和下一个字符的值,若当前值小于下一个值则减去当前值,否则加上当前值,同时根据情况移动指针。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 14:59:52