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

为何使用jr $ra会导致MIPS汇编程序陷入无限循环?

问题分析与修复方案

核心问题拆解

  1. 无限循环的根源
    你定义的exit标签被两个分支共享:main中的错误处理分支,以及product函数的结束分支。当main触发错误处理(比如last < first)时,跳去exit执行jr $ra,但main是程序入口,此时$ra的初始值不确定,执行jr $ra会跳回非法地址,导致无限循环。另外,如果你把main末尾的li $v0,10换成jr $ra,main本身没有上级调用,同样会因为$ra无效引发循环。

  2. $v0值始终为10的问题
    你在调用product后执行了li $v0,10,这行代码直接把$v0设为10,覆盖了原本要存储的乘积结果,随后的syscall是退出程序指令,所以最终$v0固定为10。

  3. 错误处理逻辑颠倒
    需求是last大于first时$v1设为1,但你用了slt $v1, $t1, $t0——这行代码是当last < first时$v1=1,完全搞反了判断条件。

  4. 乘积未存入$v0
    你把乘积存在$t3里,但最后没有将$t3的值转移到要求的$v0寄存器中。

修正后的代码

.data
    array: .word 7 4 3 8 5 0 9 10 6 2 1  # 数组
    first: .word 2                       # 起始索引
    last: .word 4                        # 结束索引

.text
main:
    la $a0, array       # 加载数组基地址到$a0
    lw $t0, first       # 加载first到$t0
    lw $t1, last        # 加载last到$t1

    # 错误处理:last > first时$v1=1,否则0
    slt $v1, $t0, $t1   # 当first < last(即last > first)时,$v1=1
    # 若需要在last>first时直接退出,可添加:bne $v1, $zero, exit_main

    li $t3, 1           # 初始化乘积为1
    jal product         # 调用乘积计算函数

    move $v0, $t3       # 将乘积结果从$t3移到$v0

exit_main:              # 单独的程序退出入口
    li $v0, 10
    syscall             # 退出程序
    
product:
    bgt $t0, $t1, product_exit  # 如果当前索引超过last,退出函数
    
    mul $t4, $t0, 4     # 计算数组元素的字节偏移(每个word占4字节)
    add $t4, $a0, $t4   # 得到元素的内存地址
    lw $t5, 0($t4)      # 加载数组元素
    mul $t3, $t3, $t5   # 更新乘积
    
    addi $t0, $t0, 1    # 索引自增
    j product           # 循环处理下一个元素               
product_exit:
    jr $ra              # 返回main函数

关键修复点说明

  • 拆分了exit标签:新增exit_main作为程序退出的唯一入口,product_exit作为函数返回的入口,避免$ra被误用导致的无限循环。
  • 修正了错误处理的判断条件:用slt $v1, $t0, $t1实现“last>first时$v1=1”的逻辑。
  • 将乘积结果从$t3转移到$v0,满足作业要求。
  • 明确了函数调用和返回的流程:product函数执行完后通过jr $ra回到main中jal product的下一行,正确返回结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 04:04:50