Search code examples
mipsinfinite-loopmars-simulator

MIPS: Infinite loop with branches


So I have a program that takes an input from the user (integer above 0) and adds up all even numbers below it to achieve a return answer (Ex: input: 7; ans: 2 + 4 + 6 = 12).

The issue with this program is that it's meant to break out of the loop based on if my 'active even variable' ($t1) > the input. Although my program never seems to properly interpret the branch and loops indefinitely until $t1 overflows (I have checked the debugger and know that the program does run the branch line every time). Below is my code:

    .data   
    
N:       .word 0
Result:  .word 0

    .text
    
    
    .globl main
initialize:
    li $v0, 5      #getting arg1 from user
    syscall
    la $t0, N
    sw $v0, 0($t0)
    
    li $t1, 2
    li $t2, 0
main:                    
    blt $t0, $t1, fin2
fori:
    add $t2, $t2, $t1 #t2 += t1
    add $t1, $t1, 2   #t1 += 2
    
    slt $t5, $t1, $t0
    bne $t5, $zero, fori
fin:
    
    
    li $v0,1              #prints return value
    move $a0, $t2
    syscall
    
    li  $v0, 10
    syscall

fin2:
    
    
    li $v0,1              #prints return value
    move $a0, $zero
    syscall
    
    li  $v0, 10
    syscall

Solution

  • So I don't know if you NEED to be using word storage and such, but really you were just over complicating it in doing so. All you needed was a simple loop which has a counter that increments by 2, checks if it is larger than the initial value, and then add that overall value to the result

    .text    
    .globl main
    
    initialize: 
        li $v0, 5           # Getting arg1 from user
        syscall             # System call
        move $t0, $v0       # Store the input value in $t0
            
        li $t1, 0           # Initializing the result register
        li $t2, 0           # Initializing the addition/counter register
    main:                    
    
    loop:
        add $t2, $t2, 2     # Increase the value to be added by 2 (next even value)
        bge $t2, $t0, fin   # Check if the increment is larger than or equal to the initial input, if so break to finish
        add $t1, $t1, $t2   # Increment the result by adding the even value
        j loop              # jump bak to the top of the loop
    
    fin:
        li $v0,1            # let the system know an integer is going to be printed
        move $a0, $t1       # Load the result into the $a0 register (the register that prints values)
        syscall             # System Call
    
        li  $v0, 10         # Let the system know the program is going to exit
        syscall             # System Call
    

    So as you can see $t2 increments by 2 each time. After each increment it is compared to the input value. If the input ($t0) than $t2 then add the value of $t2 to the result ($t1). This way there is an increment counter which is also used to add the necessary even value to the result.


    Edit:

    Not sure if this is entirely what you meant but I just tossed in some loads and saves, using the s registers as those are the register that are supposed to be used when saving values.

    .data
    
    N:      .word 0
    Result: .word 0
    
    .text    
    
    .globl main
    
    initialize:
        li $v0, 5           # Getting arg1 from user
        syscall             # System Call
        la $s0, N           # Load the address of N into $s0
        sw $v0, 0($s0)      # Store the input value in 0 index of N
                    
        li $t2, 0           # Initializing the addition/counter register
    
        la $s1, Result      # Load the address of Result into $s1
    main:                    
        sw $t2, 0($s1)      # Setting the 0 index of Result to 0
    loop:
        add $t2, $t2, 2     # Increase the value to be added by 2 (next even value)
        lw  $t4, 0($s0)     # Loading the input value into the $t4 register
        bge $t2, $t4, fin   # Check if the increment is larger than or equal to the initial input, if so break to finish
        lw  $t4, 0($s1)     # Loading the current result into the $t4 register
        add $t4, $t4, $t2   # Increment the result by adding the even value
        sw $t4, 0($s1)      # Saving the new current result into the $t4 register
        j loop              # jump bak to the top of the loop
    
    fin:
        li $v0,1            # let the system know an integer is going to be printed
        lw $a0, 0($s1)      # Load the result into the $a0 register (the register that prints values)
        syscall             # System Call
    
        li  $v0, 10         # Let the system know the program is going to exit
        syscall             # System Call