Procedure Calls

General Background

·        As registers are the fastest place to hold data, MIPS uses them as much as possible for procedure calls.

Register Name

Usage

$a0 - $a3

arguments for the procedure

$v0 - $v1

return values

$ra

return address

$fp

frame pointer

$sp

stack pointer

$gp

global pointer

·        For procedures, MIPS includes the instruction jal, jump and link, which jumps to the address of the procedure and simultaneously saves the return address (Program Counter + 4) in register $ra.

·        To return from a procedure, the jump register instruction, jr, is used as follows:jr$ra

·        The stack pointer register, $sp, is used to save registers needed by the called procedure.

·        The global pointer, $gp, is used to access static variables.

·        Local variables to a procedure that don't fit in registers are stored on the stack. See Procedure Frame below.

·        Nested procedures call other procedures while leaf procedures don't.Thus leaf procedures will be less complicated as they do not need to manage as much overhead in the procedure frame as nested procedures do.

Leaf Procedures

·        A leaf procedure follows these basic steps

1.      Save registers used by the procedure.

- create space on the stack.

- store the registers.

¨                    $t0 - $t9registers not preseved by called procedure.

¨                    $s0 - $s7 registers that must be saved by procedure if used.

2.      Place the result in the return value register $v0.

3.      Restore registers saved in step 1.

- load registers.

- adjust stack pointer.

4.      End procedure with a jump register instruction,jr$ra.

Nested Procedures

·        To avoid register usage conflicts with nested procedures, a non leaf procedure pushes any argument and temporary registers that are needed after a call to a routine onto the stack.The frame pointer and global pointer are also saved.

·        The stack pointer, return address, and the stack above the stack pointer are also preseved across a call.

·        Upon return the registers are restored from memory and the stack pointer is adjusted.

Procedure Frame

·        Known as the stack frame or activation record.

·        Follows a Last-in First-out (LIFO) order.

·        The stack frame is a segment of the stack (block of memory) used for a variety of purposes associated with a call.It holds values passed as arguments, saves registers used by the callee the caller still needs, and provides space for local variables.

·        The stack frame is memory between the frame pointer ($fp, which points to the base or first word of the frame) and the stack pointer ($sp, which points to the top or last word of the frame).The frame pointer allows a stable base register within a procedure for local memory references unlike the stack pointer that might change.The benefits of using a $fp is it's easier to use than the $sp, but, the drawback is it takes more time to set up the $fp.The use of the frame pointer is compiler dependent.



Procedure Call Details

·        Before the Call

1.      Pass arguments into registers $a0 - $a3 from left to right, and spill any other arguments by pushing onto the stack from right to left.

2.      Caller saves unpreserved registers it expects to use ($a0 - $a3, $t0 - $t9) after called procedure returns.

3.      Execute a jal instruction to jump to a callees first instruction and save the return address in $ra.

·        Just as the Call starts - setting up the stack frame

1.      Allocate memory for the frame by subtracting the frame size from the stack pointer.Calling convention requires a minimum size of 24 bytes and the stack pointer is kept double word aligned.

2.      Save callee-saved registers.The registers $s0 - $s7 must be saved if the procedure will use them.The frame pointer, $fp, register must be saved by every procedure that allocates a new stack frame.The register $ra must be saved if the callee is not a leaf procedure.

3.      Establish the stack frame pointer by adding the stack frame's size minus 4 to the $sp and store the sum in the register $fp.

·        When the callee returns to the caller.

1.      If the callee is a funtion, it places the return values in registers $v0 - $v1.

2.      restore all callee-saved registers.

3.      Pop the stack frame by adding the frame size to the $sp register.

4.      Execute a jr instruction to $ra.


MIPS Home