Debugging "invalid program counter value: 0x00000000" in MARS, function that calls other functions

27 Views Asked by At

The homework assignment:

Implement a subprogram which takes 4 numbers in the argument registers $a0...$a3 and returns the largest value and the average in $v0 and $v1 to the calling program. Note the use of the variables var0...var3. Because the values of $a0 and $a1 (at least) are changed on the call to getLarger, they will not be available when they are needed to calculate the average and must be stored on the stack. To do this problem correctly, you must calculate the maximum value using the getLarger subprogram shown here, and it must be called before the average is calculated. This implies that at a minimum $a0 and $a1 must be stored on the stack, though I would suggest all four be stack variables as shown here. It is possible to create a solution which does not require the use of the stack variables, for example by simply calculating the average first. Such solutions do not answer the issue of how to handle variables that change using the stack and are thus incorrect.

This is where im at with my code but i can not fix an error that says "Error in : invalid program counter value: 0x00000000". Any help is greatly appreciated.

.data

.text
.globl main

# Subprogram getLarger($a0, $a1)
getLarger:
    # Function prologue
    # $a0 = arg1, $a1 = arg2

    # Copy $a0 to $v0
    move $v0, $a0

    # Compare $a1 and $a0
    bgt $a1, $a0, greater_than
    move $v0, $a0
    j end_getLarger
    nop

greater_than:
    move $v0, $a1

end_getLarger:
    # Function epilogue
    jr $ra
    nop

# Subprogram largestAndAverage($a0, $a1, $a2, $a3)
largestAndAverage:
    # Function prologue
    # $a0 = arg1, $a1 = arg2, $a2 = arg3, $a3 = arg4

    # Save input arguments to local variables
    move $t0, $a0 # var0 = $a0
    move $t1, $a1 # var1 = $a1
    move $t2, $a2 # var2 = $a2
    move $t3, $a3 # var3 = $a3

    # Find the largest among $a1, $a2, $a3
    move $s0, $a1
    jal getLarger
    move $s0, $v0 # $s0 = getLarger($a1, $a2)
    move $a0, $s0
    move $a1, $a3
    jal getLarger
    move $v0, $s0 # $v0 = getLarger($s0, $a3)

    # $v0 contains the largest value[enter image description here](https://i.stack.imgur.com/p9pkE.png)

    # Calculate the average
    add $t4, $t0, $t1 # var0 + var1
    add $t4, $t4, $t2 # var0 + var1 + var2
    add $t4, $t4, $t3 # var0 + var1 + var2 + var3
    li $t5, 4         # Load immediate 4 into $t5
    div $t4, $t5      # (var0 + var1 + var2 + var3) / 4

    move $v1, $t4 # $v1 = average

    # Function epilogue
    jr $ra
    nop

# Main program
main:
    # Providing arguments 2, 5, 8, 11
    li $a0, 2
    li $a1, 5
    li $a2, 8
    li $a3, 11

    # Calling largestAndAverage subroutine
    jal largestAndAverage

    # Exit the program
    li $v0, 10
    syscall
0

There are 0 best solutions below