MIPS Assembly, Stack and Procedure Calls
MIPS Assembly, Stack and Procedure Calls
$f0, $f2, $f4, $f6, (double precision) $f1, $f3, $f5, (single precision)
system bus
$sp
Stack
Memory Organization
Memory access is done via loads and stores exclusively: lw $t0, 64($gp) $t0=Memory[$gp+64] sw $t1, 32($gp) Memory[$gp+32]=$t1 byte offset lb, sb: bytes lh, sh: half-words
Dynamic data $gp 1000 8000 hex 1000 0000 hex Text pc 0040 0000 hex Reserved 0 Static data
13.3
OP
rs
rt
rd
shamt
funct
OP
rs
rt
address/immediate
displacement (offset)
Example: addi $t0, $s0, 32 810 1610 810 3210 sw $t0, 12($s0) 4310 1610 810 1210
13.5
OP Example:
target address
13.6
Addressing Modes
Different Ways of Accessing Data in Assembly
(1) (2) (3) (4) (5) Register addressing: operands are registers. Displacement addressing: operand is at a memory location given by c($reg). Immediate addressing: operand is a constant in the instruction. PC-relative addressing: address is $pc plus a constant in the instruction. Pseudo-direct addressing: address is the constant in 26 bits of the instruction concatenated with the upper bits of $pc.
13.7
Addressing Modes
Registers Register Memory
Register
Byte
Halfword
Word
PC
Word
Word
13.8
$sp
1) Arguments: if I have more than four: put the first four into registers $a0, $a1, $a2 and $a3, then push the rest onto the stack.
low
13.9
Argument 6 Argument 5
1) Arguments: if I have more than four: put the first four into registers $a0, $a1, $a2 and $a3, then push the rest onto the stack. $sp Note that: Argument 5 is at Memory[$sp+0] Argument 6 is at Memory[$sp+4] Argument 7 is at Memory[$sp+8]
low
13.10
10
2) Set the value of $fp to $sp. 3) Use the stack to save the value of registers that I want to preserve across the procedure call.
The procedure may re-use $a0-$a3 and $t0-$9 without saving the contents; if that info is valuable to me, I must save it myself. The procedure should not touch registers $s0-$s7.
$fp
$sp
Note that arguments and registers can be easily addressed as $fp plus or minus some offset.
low
13.11
11
3) Jump to the procedure code using the jal instruction, which saves $pc+4 in register $ra.
Argument 6 Argument 5 Saved Registers
$fp
$sp
low
13.12
12
a) Allocate space for the callees frame, a portion of memory that is big enough to hold space for the variables in this procedure and also the registers that it manipulates: $sp = $sp frame size $sp frame
$fp Note that, by convention, a frame must be at least size 24 bytes: 4 words to save $a0..$a3 plus $ra padded to a double-word boundary. If you also need to save $fp, you need another double-word. Min. frame size = 32 bytes.
$sp
13.13
low
13
b) Save registers in the frame. At the very least, $fp needs to be saved (if this procedure calls another procedure, $ra must also be saved): Memory[$sp+0] = $fp Memory[$sp+4] = $ra Question: How do you frame size-8 know what registers should be saved? Check the conventions in Figure 3.13. $sp
13.14
frame
$ra $fp
low
14
$fp frame
$ra $fp
low
$sp
13.15
15
d) Do what the procedure has to do. Question: Where are the arguments that were passed in by the caller? Answer: Within some offset from the old value of $fp (when the callee started executing) saved on the frame. e) If there is a value to return to the caller, put it in $v0. $sp f) Restored saved registers.
13.16
$fp
frame
$ra $fp
low
16
g) Pop out stack frame: $sp = $sp + frame size h) Return to caller with a jump to $ra: $sp jr $ra Note: If the address of the jump is in a register, you cant use j! PH2 has a typo at p.A-28:
jr $ra # Return to caller
13.17
low
17
$fp
$sp
low
13.18
18
$sp
5) Use value saved on the stack to restore the saved registers. 6) Clean up the stack by popping out the saved registers and the arguments for the procedure call.
low
13.19
19