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

MIPS汇编模拟中代码无法终止运行问题求助

MIPS汇编程序陷入无限循环超时的问题修复

核心问题分析

你的程序超时并非end处的无限循环本身,而是代码执行流程出现异常,导致程序根本没走到end就提前进入死循环,或是栈/寄存器管理错误引发的执行混乱:

  • addAtStart未恢复栈帧和寄存器就返回:在addNode中你为s0-s2和$ra分配了栈空间并保存,但addAtStart直接通过jr $ra返回,没有恢复栈指针和保存的寄存器。这会导致栈指针错位、返回地址错误,程序大概率跳转到非法地址或进入无限循环。
  • findNode未正确设置返回值$v0:你注释说明findNode要返回目标节点的地址到$v0,但代码全程没有将$t0(当前节点)赋值给$v0,导致addNode后续操作使用未定义的$v0值,引发内存访问错误或执行流程混乱。
  • findNode循环计数逻辑错误:要插入到位置n(n>0)时,需要找到第n-1个节点挂载新节点,但当前循环从0开始计数,第一次递增后就判断是否等于n,会错误返回第0个节点而非目标节点。

修复后的完整代码

main:
    jal addNode              # 调用addNode插入新节点
    move $s3, $v0            # 将返回值存入$s3
    j end                    # 跳转到end终止程序

addNode:
    addi $sp, $sp, -16       # 分配栈空间保存寄存器
    sw $ra, 12($sp)          # 保存返回地址$ra
    sw $s0, 8($sp)           # 保存头节点head
    sw $s1, 4($sp)           # 保存新节点newNode
    sw $s2, 0($sp)           # 保存插入位置n

    beq $s2, $zero, addAtStart  # 如果n=0,跳转到头部插入逻辑

    # 准备调用findNode
    move $a0, $s0            # 传入头节点作为参数
    move $a1, $s2            # 传入插入位置n作为参数
    jal findNode             # 调用findNode

    # 在找到的节点后插入新节点
    lw $t0, 4($v0)           # 加载当前节点的下一个节点地址
    sw $t0, 4($s1)           # 设置新节点的next为当前节点的下一个节点
    sw $s1, 4($v0)           # 设置当前节点的next为新节点

    # 加载新节点的值作为返回值
    lw $v0, 0($s1)           

    # 恢复寄存器并返回
    lw $s2, 0($sp)
    lw $s1, 4($sp)
    lw $s0, 8($sp)
    lw $ra, 12($sp)
    addi $sp, $sp, 16
    jr $ra

addAtStart:
    sw $s0, 4($s1)           # 设置新节点的next为当前头节点
    move $s0, $s1            # 更新头节点为新节点
    lw $v0, 0($s1)           # 加载新节点的值作为返回值
    # 恢复寄存器和栈帧,和addNode的返回逻辑一致
    lw $s2, 0($sp)
    lw $s1, 4($sp)
    lw $s0, 8($sp)
    lw $ra, 12($sp)
    addi $sp, $sp, 16
    jr $ra                   # 返回至main

findNode:
    ori $t2, $zero, 0         # 初始化循环计数器为0
    move $t0, $a0             # $t0指向当前节点,初始为头节点

    beq $a1, $zero, findNode_exit  # 如果n=0,直接退出(外部已处理头部插入)

loop_findNode:
    # 先移动到下一个节点,再递增计数器
    lw $t0, 4($t0)             # 移动到下一个节点
    beq $t0, $zero, findNode_exit # 如果到达链表末尾,退出循环
    addi $t2, $t2, 1           # 递增计数器
    bne $t2, $a1, loop_findNode # 未到达目标位置,继续循环

findNode_exit:
    move $v0, $t0             # 将目标节点地址存入$v0作为返回值
    jr $ra                     # 返回至调用者

end:
    j end                    # 无限循环终止程序

关键修复点说明

  • 修复addAtStart的栈帧恢复:在addAtStart末尾添加和addNode相同的寄存器恢复和栈指针调整代码,确保返回时栈状态正确、返回地址有效。
  • 修复findNode的返回值:在findNode_exit处将$t0(目标节点地址)赋值给$v0,保证调用者能拿到正确的节点地址。
  • 调整findNode的循环逻辑:先移动节点再递增计数器,确保当n=1时能找到第0个节点的下一个节点,匹配插入逻辑的需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 19:16:26