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