MIPS Calling Convention Chapter 2.7 Appendix A.6 Procedure Calls Main Procedure Call Procedure Call Procedure Procedure Calls Procedure must from any call Procedure uses that main was using We need a convention to Name $zero $v0-$v1 $a0-$a3 $t0-$t7 $s0-$s7 $t8-$t9 $gp 0 2-3 4-7 8-15 16-23 24-25 28 29 30 31 MIPS-specific info Reg Number Usage Saved Page 140, Figure 3.13 The constant 0 Function results Function Arguments Temporaries More temporaries Global pointer Stack pointer Frame pointer Return address Preserved across call? MIPS-specific info who cares? Preserved Value is same after call Caller Procedure t preserved guarantees Caller Procedure 1
Steps for caller 1. Store away any temporary registers we want 2. Pass function parameters to procedure 3. Transfer control to procedure 4. (then procedure executes) 5. Get return value 6. Restore any temp regs we saved away Steps for procedure 1. Allocate stack space 2. Store preserved regs we may use 3. Perform task 4. Place result in proper location for caller 5. Restore preserved regs we may have used 6. Transfer control back to caller Write the caller & procedure code for the following function: int MyFunc(int g, int h) { return (g + h);} Caller: Assume: g,h are in $s2,$s3. We want return value in $s0. Caller wants to preserve $t0 across function call. Callee: How do we know how much space until we know how many regs to store? Steps for procedure How do we know what we ll use until we write task code? 1. Allocate stack space 2. Store preserved regs we may use 3. Perform task 4. Place result in proper location for caller 5. Restore preserved regs we may have used 6. Transfer control back to caller Definitions Leaf function Makes no function calls n-leaf function Contains a function call 2
Allocating stack space How much stack space? Minimum allocation: 24 bytes Only allocate once per function!!!! contains address of bottom of stack. What operation on allocates space? Stack space for this function Minimum allocation 24 bytes, even if unused. 4 words for $a0-$a3 in case we need it Preserved registers that we destroy (i.e. $s0) Local variables declared in our function Any other outgoing arguments (non-leaf) Total bytes must be divisible by 8 (aligned for floating-point numbers) What actually goes in stack Assume it needs 2 saved registers Example before call P*4 bytes for preserved regs ($s0-$s7) L*4 bytes for local data A*4 bytes for outgoing args Extra Arguments preserved registers (and $a0-$a3) padding local data Extra outgoing arguments int foo(int arg1, int arg2) { int myarray[64]; myarray[3] = 5; } bar(a1, a2, a3, a4, a5); return (myarray[3]); Local 256- byte array n-leaf function, 5 outgoing args addi,, - (1+64+1+2+6)*4 sw, 73*4() sw, 72*4() sw $s1, 67*4() sw $s0, 66*4() before call addi $t0, $zero,5 # $t0 = 5 sw $t0, (1+3)*4 ()# myarray[3] = 5 lw, 73*4() lw, 72*4() lw $s1, 67*4() lw $s0, 66*4() addi,, (1+64+1+2+6)*4 jr Caller s Stack $a0 $a1 $a2 $a3 $s1 $s0 padding myarray outgoing arg 5 3
Recursive call: SumToN int SumToN(int N) { if (N < 2) return 1; else return (SumToN(N-1) + N); } Both the caller and the callee!!! addi,, -24 sw, 20 () sw, 16 () addi,, 20 result: sw $a0, 0 () lw $a0, 0 () end: lw, 20 () lw, 16 () addi,, 24 jr SumToN(2) addi,, -24 sw, 20 () sw, 16 () addi,, 20 result: sw $a0, 0 () lw $a0, 0 () end: lw, 20 () lw, 16 () addi,, 24 jr SumToN(2) addi,, -24 sw, 20 () sw, 16 () addi,, 20 result: sw $a0, 0 () lw $a0, 0 () end: lw, 20 () lw, 16 () addi,, 24 jr SumToN(2) addi,, -24 sw, 20 () sw, 16 () addi,, 20 result: sw $a0, 0 () lw $a0, 0 () end: lw, 20 () lw, 16 () addi,, 24 jr SumToN(2) addi,, -24 sw, 20 () sw, 16 () addi,, 20 result: sw $a0, 0 () lw $a0, 0 () end: lw, 20 () lw, 16 () addi,, 24 jr SumToN(1) 4
addi,, -24 sw, 20 () sw, 16 () addi,, 20 result: sw $a0, 0 () lw $a0, 0 () end: lw, 20 () lw, 16 () addi,, 24 jr SumToN(1) $v0 = 1 addi,, -24 sw, 20 () sw, 16 () addi,, 20 result: sw $a0, 0 () lw $a0, 0 () end: lw, 20 () lw, 16 () addi,, 24 jr SumToN(1) $v0 = 1 addi,, -24 sw, 20 () sw, 16 () addi,, 20 result: sw $a0, 0 () lw $a0, 0 () end: lw, 20 () lw, 16 () addi,, 24 jr SumToN(2) addi,, -24 sw, 20 () sw, 16 () addi,, 20 result: sw $a0, 0 () lw $a0, 0 () end: lw, 20 () lw, 16 () addi,, 24 jr SumToN(2) addi,, -24 sw, 20 () sw, 16 () addi,, 20 result: sw $a0, 0 () lw $a0, 0 () end: lw, 20 () lw, 16 () addi,, 24 jr SumToN(2) What about the garbage in the stack? MIPS instructions Rule: Destination register always comes first Exception: Rule: Any instruction involving constants has i at the end of instruction(add vs addi) Exception: 5