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

MIPS程序出现无限循环问题求助:疑似循环初始化异常

MIPS嵌套循环无限循环问题排查

我编写的MIPS程序存在无限循环问题,程序里的嵌套for循环包含多个条件判断语句,我怀疑是循环初始化环节导致的,但不确定具体问题。以下是两种出现循环异常的代码片段:

第一种写法的问题代码

li $t7, 0 # i=0
    bge $t7, $s0, exit_i # i < trackHeight
    addi $t7, $t7, 1 # i++
    # j forDraw_1 # loop while i=0
    
    i_plus:
    li $t8, 0 # j=0
    bge $t8, $s1, exit_j # j < trackWidth
    addi $t8, $t8, 1 # j++
    # j i_plus # loop while j=0
    
        # j_plus:
        if_1:
        beq $t7, $zero, drawBorder # i==0
        beq $t8, $zero, drawBorder # j==0
        
        addi $t9, $s0, -1 # trackHeight -1
        beq $t7, $t9, drawBorder # i== t.h -1
        
        addi $t5, $s1, -1 # trackWidth -1
        beq $t8, $t5, drawBorder # j== t.w -1
        
        # else if 1
        beq $t7, $s2, draw219 # i == x
        beq $t8, $s3, draw219 # j == y
        # else if 2
        #beq $t7, $s2, draw219 # i == x
        addi $t4, $s3, -1 # y-1
        beq $t8, $t4, draw219 # j == y-1
        # else if 3
        #beq $t7, $s2, draw56 # i == x
        addi $t4, $t4, 2 # y-1 --> y+1
        beq $t8, $t4, draw56 # j == y+1
        # else if 4
        addi $t3, $s2, 1 # x+1
        beq $t7, $t3, draw254 # i == x+1
        #addi $t4, $t4, -1 # j back to 0
        #beq $t8, $s3, draw254 # j == y
        # else if 5
        addi $t3, $t3, -2 # x+1 --> x-1
        beq $t7, $t3, draw127 # i == x-1
        #beq $t8, $s3, draw127 # j == y
        # else if 6
        addi $t4, $zero, 10
        ble $t8, $zero, printLane # j>0
        div $t8, $t4
        mfhi $t5
        beqz $t5, printLane
        
        
        drawBorder:
        li $v0, 4
        la $a0, outsideBorder
        syscall
        j if_1
        
        printLane:
        li $v0, 4
        la $a0, lanes
        syscall
    
        draw219:
        li $t5, 219
        move $a0, $t5
        li $v0, 11
        syscall
        
        draw56:
        li $t5, 56
        move $a0, $t5
        li $v0, 11
        syscall
        
        draw254:
        li $t5, 254
        move $a0, $t5
        li $v0, 11
        syscall
        
        draw127:
        li $t5, 127
        move $a0, $t5
        li $v0, 11
        syscall

第二种写法的问题代码

bne $t7, $zero, else_if1 # i==0
        bne $t8, $zero, else_if1  # j==0
        
        addi $t9, $s0, -1 # trackHeight -1
        bne $t7, $t9, else_if1  # i== t.h -1
        
        addi $t5, $s1, -1 # trackWidth -1
        bne $t8, $t5, else_if1  # j== t.w -1
        
        li $v0, 4
        la $a0, outsideBorder
        syscall
        
        else_if1:
        bne $t7, $s2, else_if2 # i == x
        bne $t8, $s3, else_if2 # j == y
        li $t5, 219
        move $a0, $t5
        li $v0, 11
        syscall
        
        else_if2:
        beq $t7, $s2, else_if3 # i == x
        addi $t4, $s3, -1 # y-1
        bne $t8, $t4, else_if3 # j == y-1
        li $t5, 219
        move $a0, $t5
        li $v0, 11
        syscall
        
        else_if3:
        beq $t7, $s2, else_if4 # i == x
        addi $t4, $t4, 2 # y-1 --> y+1
        bne $t8, $t4, else_if4 # j == y+1
        li $t5, 56
        move $a0, $t5
        li $v0, 11
        syscall
        
        else_if4:
        addi $t3, $s2, 1 # x+1
        bne $t7, $t3, else_if5 # i == x+1
        #addi $t4, $t4, -1 # j back to 0
        beq $t8, $s3, else_if5 # j == y
        li $t5, 254
        move $a0, $t5
        li $v0, 11
        syscall
        
        else_if5:
        addi $t3, $t3, -2 # x+1 --> x-1
        bne $t7, $t3, else_if6 # i == x-1
        beq $t8, $s3, else_if6  # j == y
        li $t5, 127
        move $a0, $t5
        li $v0, 11
        syscall
        
        else_if6:
        addi $t4, $zero, 10
        ble $t8, $zero, printLane # j>0
        div $t8, $t4
        mfhi $t5
        beqz $t5, printLane
        li $v0, 4
        la $a0, lanes
        syscall

核心问题分析

  1. 循环结构完全错误:
    外层i循环和内层j循环都没有正确的循环跳转逻辑——原本的循环跳转指令被注释掉(比如# j forDraw_1),而且循环变量的递增操作放在条件判断之后,导致循环只执行一次甚至直接跳过循环体,完全不符合for循环的标准执行流程(初始化→条件判断→执行循环体→变量递增→跳转回判断)。

  2. 错误的分支跳转导致死循环:
    第一种写法里的drawBorder标签下有j if_1指令,执行完绘制操作后直接跳回if_1的条件判断,完全绕开了循环变量的递增和循环终止条件的检查,导致程序一直卡在条件判断和绘制的死循环里。

  3. 条件判断逻辑缺失分支退出:
    两种写法的条件判断都没有处理“满足条件后跳过后续判断”的逻辑,比如满足drawBorder的条件后,执行完绘制应该跳转到循环的递增步骤,而不是继续执行后面的else if判断,这会导致程序流混乱,重复执行无效代码。

修正思路

1. 重构循环结构

按照标准for循环流程编写嵌套循环:

# 外层i循环
li $t7, 0          # i = 0
for_i:
    bge $t7, $s0, exit_i  # 当i >= trackHeight时退出循环
    # 内层j循环开始
    li $t8, 0      # j = 0
    for_j:
        bge $t8, $s1, exit_j  # 当j >= trackWidth时退出内层循环
        # 这里放所有条件判断和绘制逻辑
        addi $t8, $t8, 1  # j++
        j for_j           # 跳回内层循环判断
    exit_j:
    addi $t7, $t7, 1      # i++
    j for_i               # 跳回外层循环判断
exit_i:

2. 修正条件判断的分支跳转

每个条件满足执行完绘制后,要跳转到循环变量递增的位置,避免重复执行后续判断,比如:

if_1:
beq $t7, $zero, drawBorder
# 其他条件判断...

drawBorder:
li $v0, 4
la $a0, outsideBorder
syscall
j increment_j  # 跳转到j的递增步骤,而不是回到if_1

increment_j:
addi $t8, $t8, 1
j for_j

3. 移除无效的跳转指令

删除第一种写法里drawBorder下的j if_1,避免程序卡在条件判断循环中。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 11:05:22