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
核心问题分析
循环结构完全错误:
外层i循环和内层j循环都没有正确的循环跳转逻辑——原本的循环跳转指令被注释掉(比如# j forDraw_1),而且循环变量的递增操作放在条件判断之后,导致循环只执行一次甚至直接跳过循环体,完全不符合for循环的标准执行流程(初始化→条件判断→执行循环体→变量递增→跳转回判断)。错误的分支跳转导致死循环:
第一种写法里的drawBorder标签下有j if_1指令,执行完绘制操作后直接跳回if_1的条件判断,完全绕开了循环变量的递增和循环终止条件的检查,导致程序一直卡在条件判断和绘制的死循环里。条件判断逻辑缺失分支退出:
两种写法的条件判断都没有处理“满足条件后跳过后续判断”的逻辑,比如满足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
相关产品推荐
相关产品推荐

