1

so I have an issue with my program. I have a for loop with a bunch of multi conditional if statements in it and when it runs, it is giving me an infinite loop. This is the portion of the whole program where the loop is happening

        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

I also tried writing it in a different format, but also got an infinite loop. This is the other format. Not sure what is wrong, but i have a strong feeling it is coming from the initialization of the loop

                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
  • 3
    This is an excellent opportunity to develop your debugging skills. Single step debugging in assembly is the same as in other languages as follows: single step line-by-line and verify behavior of each line, namely that the program state is updated as expected, and, that the next line to run is the expected one. If any one line/instruction is wrong or missing, the program won't run as expected, and you will be able to see this in debugging. Commented Nov 30, 2022 at 22:01

1 Answer 1

1

Generally, a good nested loop structure should look something like this. Assume n and m are constants.

# 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

A few notes:

  • It helps to indent your code to show the nesting of your loops. Many assemblers don't allow the indenting of code labels, but most allow you to indent your code.
  • The labels loop_i_overhead and loop_j_overhead are optional, but are very handy if you need to skip to them. Also, they help keep the loop overhead mentally separate from the "action," so to speak.
  • Notice that the loop counter for the outer loop is initialized outside the loop. Otherwise, the loop will loop forever since its exit condition will never be met. It's very easy to accidentally do this:
myloop:
move $t0,$zero # init loop counter

# your code goes here

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

The intent was to loop MAX_INT+1 times, but in reality the loop counter is reset to zero at the start of every iteration so the loop will go on forever. Moving the loop counter initialization above the loop label solves this problem.

Sign up to request clarification or add additional context in comments.

2 Comments

If you don't need the counter value inside the loop, it's also common to use fewer registers and less setup by just counting down towards zero. i=n ; do{ ...; --i; }while(i != 0);. That only saves instructions for the outer loop, since you don't need n again.
True, I was trying to keep things simple at the expense of optimization.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.