im working on a program that uses a stack frame in order to call functions recursively to help calculate the nth term of the fibonnacci sequence this is what i have so far but the output (which would be in register $t7 by the time the program stops running) returns 1. this is my progress so far
.text
.globl main
main:
li $v0, 4
la $a0, prompt
syscall
li $v0, 5
syscall
addiu $sp, $sp, -4
sw $t0, ($sp)
addiu $sp, $sp, -4
sw $t1, ($sp)
addiu $sp, $sp, -4 # space for parameters
sw $v0, ($sp) # pushing parameter
jal fib
addiu $sp, $sp, 4
lw $t1, ($sp)
addiu $sp, $sp, 4
lw $t0, ($sp)
addiu $sp, $sp, 4
move $t7, $v0
li $v0, 10
syscall
fib:
addiu $sp, $sp, -4
sw $ra, ($sp)
addiu $sp, $sp, -4
sw $fp, ($sp)
addiu $sp, $sp, -4
sw $s0, ($sp)
addiu $sp, $sp, -4
sw $s1, ($sp)
addiu $fp, $sp, -8
move $sp, $fp
lw $t3, 24($fp) # t3 = n of fib(int n)
move $s0, $t3
li $v0, 1 # return value
ble $s0, 1, epilog #
addi $s0, $s0, -1 # setting up fib(n-1)
jal fib
move $s0, $v0 # store fib(n-1)
addi $s0, $s0, -2 # set up fib(n-2)
jal fib
add $v0, $s1, $v0 # add fib(n-1) and fib(n-2)
epilog:
addiu $sp, $fp, 8 #
lw $s1, ($sp)
addiu $sp, $sp, 4
lw $s0, ($sp)
addiu $sp, $sp, 4
lw $fp, ($sp)
addiu $sp, $sp, 4
lw $ra, ($sp)
jr $ra
li $v0, 10
syscall
.data
prompt: .asciiz "enter a number dingus \n"
i feel like its my recursive function in the body of the subroutine, but ive been staring at this for the past couple hours and still have no idea what im doing wrong, any tips would be appreciated, thanks.
The first time you enter
fib, after pushing your registers in the function prologue, the stack looks like this:This chart is by no means standardized anywhere but it's a tool I like to use to visualize the stack frames of a function.
Then your function loads
$s0from24(fp)which corresponds to the$t0you pushed at the start. That's all well and good, but what happens for thefib(n-1)case? The function is called again, and the prologue is executed a second time. Now the stack looks like this:Do you see the problem now? Offset
24(fp)no longer points to your prior argument. So you're not loading the$s0you pushed anymore when you recurse. Instead you're loading who knows what.Now, if you moved this section inside the function, you'd be loading from the correct offset for your temporary variable.