I am getting the error "line 31: Runtime exception at 0x00400038: address out of range 0x7fbffffc
Go: execution terminated with errors." whenever I input 2, when I input 3 it outputs 3, when I input 4 it outputs 4 instead of 8
the code is supposed to do
int Myfun (int N)
{
if (N>3) return ( Myfun(N-2) + 2N );
else return 0
}
my code is
.data
input: .asciiz "Input: "
.text
.globl main
main:
# Prompt user for input
li $v0, 4
la $a0, input
syscall
# Get user input
li $v0, 5
syscall
move $a0, $v0
# Call Myfun(N)
jal Myfun
# Print the result
li $v0, 1
syscall
# Exit
li $v0, 10
syscall
Myfun:
addi $sp, $sp, -8 # Reserve stack space for 2 items
sw $ra, 4($sp) # Save the return address
sw $a0, 0($sp) # Save the current value of N
slti $t0, $a0, 3 # Test if N is less than 3
beq $t0, $zero, Base_case # If N < 3, jump to base_case
addi $a0, $a0, -2 # Prepare the argument for the recursive
jal Myfun # Recursive call
lw $a0, 0($sp) # After returning, load the original N
add $t1, $a0, $a0 # Calculate 2N
add $v0, $v0, $t1 # Add 2N to the result of the recursive
j Exit # Return from the function
Base_case:
li $v0, 0 # Set the return value to 0 for the base case
j Exit
Exit:
lw $a0, 0($sp)
lw $ra, 4($sp) # Restore the return address
addi $sp, $sp, 8 # Clean up the stack
jr $ra # Return from the function
You have two simple problems that can be identified by debugging.
First, in
mainyou're printing$a0instead of the return value from the function, which is in$v0. So, inmainafterjal Myfun, you need to move$v0(the return value) into$a0for the syscall #1 to print an integer.Second, in
Myfun, you have reversed the if-statement condition so that the function won't converge when given an input less than 3 — classic stack overflow.You have coded the following:
Also, by the calling convention, there's no reason to reload
$a0in function epilog.As you're doing, you do need to save
$a0at the beginning so that you can reload it (restore theNvalue) for the+2*Ncomputation for your function's own benefit, but otherwise don't need to restore$a0for the benefit of any callers, as$a0is a call-clobbered register, so it would be inappropriate for callers to rely on that register having the same value after a function call as it might have before a function call (unless custom calling convention).