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.
|