Subroutines (Cont.)
By software convention (not by hardware) registers have been assigned different roles:
$t0
- $t9
— The subroutine is free to change these registers.
$s0
- $s7
— The subroutine must not change these registers.
$a0
- $a3
— These registers contain arguments for the subroutine.
The subroutine can change them.
$v0
- $v1
— These registers contain values returned from the subroutine.
The following are the guidelines for using the temporary and saved registers, according to the convention:
- If the routine DOES NOT call any other routines, then use the temporary registers (
$t0
-$t9
or $8
-$15
and $24
-$25
) without any restrictions.
- If your routine DOES call another routine, then you cannot assume that values in the temporary registers will be left intact across the call (i.e., by convention, the called routine has a right to use these registers).
Therefore, for any value stored in a temporary register that needs to be preserved across a call,
- you must either save the register before the call and restore the value afterwards (caller-saved register), or
- assign any such values to a saved register instead (but see below).
- If you use any of the saved registers (
$s0
-$s7
or $16
-$23
), you must save their contents before you use them (callee-saved registers), and restore the values before returning.
Register values are usually saved on the system stack (i.e., the memory pointed to by $sp
).
Since saving and restoring a register is an expensive operation, it is a goal of the assembly programmer to design a register allocation scheme that minimizes the number of save/restore operations.