assembly MIPS中的无限循环-为什么会发生

ttp71kqs  于 2022-12-04  发布在  其他
关注(0)|答案(1)|浏览(115)

所以我的程序有问题。我有一个for循环,里面有一堆多条件if语句,当它运行的时候,它给了我一个无限循环。这是整个程序中循环发生的部分

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
cpjpxq1n

cpjpxq1n1#

一般来说,一个好的嵌套循环结构应该看起来像这样:假设nm是常量。

# for(i = 0;i < n;i++){
#    for (j = 0; j < m; j++)

move $t0,$zero #init loop counter. $t0 = i
li $t2,n   ;set $t2 to some constant n
li $t3,m   ;set $t3 to some constant m (there's no sense in reloading it over and over again)

loop_i:

    move $t1,$zero #$t1 = j (Reset j every time we iterate through the outer loop)

loop_j:

    # your code goes here

    loop_j_overhead: 
    addi $t1,$t1,1
    bne $t1,$t3,loop_j  #loop until $t1 = $t3 (loop as long as j < m)

loop_i_overhead: 
addi $t0,$t0,1
bne $t0,$t2,loop_i #loop until $t0 = $t2 (loop as long as i < n)

# rest of your program

注意事项:

  • 缩进代码可以帮助显示循环的嵌套。许多汇编器不允许缩进代码标签,但大多数汇编器允许缩进代码。
  • 标签loop_i_overheadloop_j_overhead是可选的,但如果你需要跳到它们,它们非常方便。
  • 注意,外部循环的循环计数器是在循环外部初始化的。否则,循环将永远循环下去,因为它的退出条件永远不会满足。很容易意外地发生这种情况:
myloop:
move $t0,$zero # init loop counter

# your code goes here

myloop_overhead:
addi $t0,$t0,1
beqz $t0,myloop

其目的是循环MAX_INT+1次,但实际上循环计数器在每次迭代开始时重置为零,因此循环将永远继续。将循环计数器初始化移至循环标签 * 上方 * 可解决此问题。

相关问题