a = a + 1;
lw $t0,12($fp) # get a addiu $t0,$t0,1 # a + 1 sw $t0,12($fp) # a =
A real-world linkage convention allows many types of objects to go into a stack frame. Our rules are much simpler:
Calling a Subroutine (done by the caller):
- Push any registers
$t0-$t9
that contain values that must be saved. Push the registers in numerical order.- Put argument values into
$a0-$a3
.- Call the subroutine using
jal
.Subroutine Prolog (done by the subroutine):
- Push
$ra
(always).- Push the caller's frame pointer
$fp
.- Push any of the registers
$s0-$s7
that the subroutine might alter.- Initialize the frame pointer:
. The "space for variables" is four times the number of local variables. (Remember that subtracting from $sp grows the stack). $fp = $sp - space_for_variables
- Initialize the stack pointer:
$sp = $fp.
![]()
Subroutine Body:
- At this point the stack looks like the picture at right.
- The subroutine may alter any "T" or "A" register, or any "S" register that it saved in the prolog.
- The subroutine refers to local variables as
.disp($fp)
- The subroutine may push and pop values on the stack using
$sp
.- If the subroutine calls another subroutine, then it does so by following these rules.
Subroutine Epilog (done at the end of the subroutine):
- Put return values in
$v0-$v1
$sp = $fp + space_for_variables
.- Pop any registers
$s0-$s7
that were previously saved in the frame.- Pop the caller's frame pointer into
$fp
.- Pop
$ra
(always).- Return to the caller using
jr $ra
.Return from a Subroutine (done by the caller):
- Pop any registers
$t0-$t9
that the caller previously pushed.