Solution (source code)

= Solution

The entry sequence creates one 12-byte <stack frame>, then preserves the <return address> and both used <callee-saved registers>:
``
subi $sp, $sp, 12    # allocate three four-byte words
sw   $ra, 0($sp)     # save return address of this activation
sw   $s0, 4($sp)     # save caller's s0
sw   $s1, 8($sp)     # save caller's s1
``
The closing sequence reverses these effects:
``
lw   $ra, 0($sp)     # recover return address of this activation
lw   $s0, 4($sp)     # restore caller's s0
lw   $s1, 8($sp)     # restore caller's s1
addi $sp, $sp, 12    # deallocate the frame
jr   $ra            # return to the caller
``
Loads must precede deallocation because their offsets refer to the current <stack frame>. The <return value> in `$v0` is deliberately retained. Saving `$ra` is essential even though it is not an `$s` <processor register>: otherwise the second nested call would destroy the address to which this activation must return.