Raptrex
Raptrex

Reputation: 4115

MIPS getting infinite loop

Im suppose to write a recursive function MinMax2D to find the minimum and maximum of a N x M matrix, assuming M>=1, and N>=1. The starting address of the Matrix, and the size N and M are passed to the function on the stack, and the results (min and max) are returned via the stack.

I cant figure out why I am getting an infinite loop.

Heres my code:

            .data
newLine:    .asciiz     "\n"
space:      .asciiz     " "
Error:      .asciiz     "Cannot of have matrix dimension < 1"
Matrix:     .word       0, 3, 4, 6, -8, 2, 4, 8, 1, 9, 10, -5, 4, 1, 3, 3, 1, -4, 5, -52
            .globl      main
            .text

main:
        addiu   $sp, $sp, -20
        la      $t0, Matrix
        lw      $t1, 0($t0)
        lw      $t2, 0($t0)
        sw      $t0, 0($sp)
        addi    $t0, $0, 4              # N
        sw      $t0, 4($sp)
        addi    $t0, $0, 5              # M
        sw      $t0, 8($sp)
        sw      $t1, 12($sp)
        sw      $t2, 16($sp)
        jal     MinMax2D

        li      $v0, 4
        la      $a0, newLine
        syscall

        lw      $a0, 12($sp)
        li      $v0, 1
        syscall

        li      $v0, 4
        la      $a0, space
        syscall

        lw      $a0, 16($sp)
        li      $v0, 1
        syscall

        addiu   $sp, $sp, 20
        li      $v0, 10
        syscall

##############################################################################
#
#   MinMax2D Method
#   Determines the min/max of the 2D Array
#
##############################################################################

MinMax2D:
        lw      $t0, 0($sp)             # Matrix
        lw      $t1, 4($sp)             # N
        lw      $t2, 8($sp)             # M
        lw      $t5, 12($sp)
        lw      $t6, 16($sp)

        blez    $t1, Err                # Checks to see if N or M <= 0
        blez    $t2, Err

        addiu   $sp, $sp, -32
        sw      $ra, 28($sp)            # Save return address
        sw      $t5, 20($sp)
        sw      $t6, 24($sp)

        addi    $t7, $0, 1
        beq     $t1, $t7, return        # Checks if N or M = 1
        beq     $t2, $t7, return
#############################################################################       
        addi    $t4, $0, 0              
Loop:                                   # Comparison Loop
        bge     $t4, $t2, Recur
        lw      $t3, 0($t0)
        addi    $t0, $t0, 4
        addi    $t4, $t4, 1
        ble     $t3, $t5, ELSE          # If(t3 <= MAX) jump ELSE
        move    $t5, $t3                # MAX = t3
        b       Loop
ELSE:   
        bgt     $t3, $t6, Loop          # If(t3 > MIN) skip, jump Loop
        move    $t6, $t3                # MIN = t3
        b       Loop
Recur:
        sw      $t0, 0($sp)             # Store matrix minus a row back to stack
        addi    $t1, $t1, -1            # Decrement row counter
        sw      $t1, 4($sp)             # Store row counter
        sw      $t2, 8($sp)             # Store column counter
        sw      $t5, 12($sp)            # Store Min
        sw      $t6, 16($sp)            # Store Max
        jal     MinMax2D                # Recursive call
        lw      $t5, 12($sp)
        lw      $t6, 16($sp)
        lw      $ra, 28($sp)
        lw      $a0, 20($sp)
        lw      $a1, 24($sp)
        blt     $a0, $t5, next1         # If(a0 < MAX) jump next1
        add     $a0, $0, $t5            
next1:
        bge     $a1, $t6, DONE
        add     $a1, $0, $t6
move1:      
        move    $t5, $a0
        move    $t6, $a1
#############################################################################   
DONE:   
        sw      $t5, 12($sp)            # Store Max
        sw      $t6, 16($sp)            # Store Min
        jr      $ra

return:
        addiu   $sp, $sp, 32
        addi    $t4, $0, 0
rLoop:
        bge     $t4, $t2, DONE          # If (t4 >= M) Done
        lw      $t3, 0($t0)     
        addi    $t0, $t0, 4
        addi    $t4, $t4, 1
        ble     $t3, $t5, ELSE1         # If (current element <= MAX) branch else1
        move    $t5, $t3                # MAX = current element
        b       rLoop
ELSE1:
        bgt     $t3, $t6, rLoop         # If(current element >= MIN) skip, branch rLoop
        move    $t6, $t3                # MIN = current element
        b       rLoop

Err:                                    # Error!!!! return 0
        sw      $0, 12($sp)             # Store Max = 0
        sw      $0, 16($sp)             # Store Min = 0

        la      $a0, Error              # Print error message
        addi    $v0, $0, 40
        syscall

        jr      $ra                     # Return

# Check for < 0 and Err:    OK
# Check N or M = 1:         OK

Upvotes: 0

Views: 2801

Answers (2)

nethageraba
nethageraba

Reputation: 5

Something that stands out to me is where you do this at the top:

la      $t0, Matrix
lw      $t1, 0($t0)
lw      $t2, 0($t0)

looks like you're loading the same word (from word array with offset=0) into both $t1 and $t2, then adding them both to the stack. Is that intentional?

Upvotes: 0

Laurent G
Laurent G

Reputation: 3184

There is a path from the return of the jal to the exit of the function (between DONE: and return:) that does not restore the stack.

Upvotes: 2

Related Questions