This is based on:
D.A. Patterson and J.L. Hennessy (1994) Computer Organisation and Design: The Hardware Software Interface, Morgan Kauffmann Publishers Inc., San Francisco.
The MIPS instruction set uses the following conventions:
The following steps are usually involved in a procedure call
/*C code where main calls A, which calls B, which calls C*/
void main(void)
{
procA();
/*more stuff*/
}
void procA(void)
{
/*other stuff*/
procB();
/*more stuff*/
}
void procB()
{
/*other stuff*/
procC();
/*more stuff*/
}
void procC()
{
/*whatever*/
}
MIPS code with the same sequence of calls
jal PROCA #$31 = PC + 4 - ie, stores address (1) below
#address (1)
..........................................
PROCA: #other stuff
addi $29,$29,-4 #moves stack pointer down by one word
sw $31,0($29) #pushes $31 content onto stack
jal PROCB #$31 = PC + 4 - ie, stores address (2)
lw $31,0($29) #address (2) - pops from memory to $31
addi $29,$29,4 #adjusts stack pointer
#more stuff
jr $31 #returns to (1) above
..........................................
PROCB: #other stuff
addi $29,$29,-4
sw $31,0($29)
jal PROCC
lw $31,0($29) #(3)
addi $29,$29,4
#more stuff
jr $31 #returns to (2) above
..........................................
PROCC: #whatever
jr $31 #returns to (3) above
Procedures usually have parameters. Parameters are conventionally saved into registers $4 to $7. Any registers that are changed by a procedure, must be restored, so that the calling procedure gets the registers back in the same state as before the procedure was called. Here is a simple example:
C code to swap contents of x and y
void swap(int* x, int* y)
{
int temp;
temp = *x;
*x = *y;
*y = temp;
}
int x,y;
/*other stuff*/
swap(&x,&y);
/*more stuff*/
Equivalent outline MIPS code: we assume that the contents of x stored in $5 and y in $6.We will use register $16 to store temp, but this register must be restored back to what it was before after the execution of swap. The stack pointer is again $29.
jal SWAP #$31 gets address of (1)
#(1)
SWAP: addi $29,$29,-4 #adjust stack pointer to save $16
sw $16, 0($29) #save $16 on stack
#main body follows
addi $16,$5,$0 #$16 = x
addi $5,$6,$0 #x = y
addi $6,$16,$0 #y = temp
#restore stack
lw $16,0($29) #$16 gets its old value back
addi $29,$29,4 #restore stack pointer
jr $31 #continue from (1) above