# Compiling fib to MIPS assembly language: # int fib(int n) { # if (n == 0 || n == 1) // compile first # return 1; // compile first # else // compile first # return fib(n-1)+fib(n-2); // compile last # } # Notes: $a0 holds n # fib will use $s0 # fib will need 3 words on the stack # first write prologue, then epilogue # then compile lines of C marked "compile first" # then compile lines of C marked "compile last" fib: prologue: addi $sp, $sp, -12 # allocate 3 words on stack sw $ra, 8($sp) # because fib will be a calleR of another # fib, must spill $ra to stack sw $s0, 4($sp) body: beq $a0, $0, return1 # if (n == 0) goto return1 addi $a0, $a0, -1 # if (n == 1) goto return1 beq $a0, $0, return1 # because subtract and beq $0 after # is same as testing for == 1 add $s0, $a0, $0 # move my $a0 to $s0 so calleE can <---------------+ # deal with saving it later | jal fib # call fib(n-1) // recall $a0 is n-1 at this point | | sw $v0, 0($sp) # take return value of fib(n-1) and spill | # to stack because calling fib(n-2) will | # overwrite $v0 | addi $a0, $s0, -1 # restore my $a0 that i put in $s0 up here ----------| # and save instruction by subtracting 1 from it # in the same step (we want n-2 anyway) jal fib # call fib(n-2) lw $t0, 0($sp) # temporarily restore old return value of fib(n-1) add $v0, $v0, $t0 # add return value of fib(n-1) with fib(n-2) # and store in my $v0 for returning j epilogue # skip over base case step in return1 return1: addi $v0, $0, 1 # base case just returns 1 epilogue: lw $ra, 8($sp) # restore registers spilled during prologue lw $s0, 4($sp) addi $sp, $sp, 12 # pop stack jr $ra # return from fib