| |
More Examples of MIPS Calling Conventions
Here is a slightly expanded version of the PowerPoint (tm) slides from the last lecture.
It is supposed to illustrate correcp MIPS calling conventions,
with no explicit frame pointer.
A call with more than 4 arguments
The first 4 arguments are in registers $a0 through $a3,
and the 5th argument is only on the stack.
# call f(0,1,2,3,4)
li $a0,0 # arg0
li $a1,1 # arg1
li $a2,2 # arg2
li $a3,3 # arg3
li $t0,4 # arg3 value
sw $t0,16($sp) # store in arg3 slot
jal f # jump to callee and link
The Callee (nonleaf)
The called function f computes a fairly complicated expression:
int f(int a, int b, int c, int d, int e) {
int temp = g(b, c);
return a + g(temp, g(d, e));
}
This function makes several calls to g with various arguments.
Recall that the argument registers $a0 through $a4
are considered caller-save, that is, their values may be changed
by a call to the external function g.
Thus, it is necessary for f to save at least some of them.
In addition, f will allocate space for variable temp
in its stack frame.
So the stack frame will look like:
The displacements printed at the left are relative to the initial stack pointer
when f is entered, or relative to framesz($sp) after
f has pushed its frame onto the stack.
The assembly language code for f looks like
f:
# prolog
addiu $sp,$sp,-framesz # push frame
sw $ra,framesz-4($sp) # save $ra
sw $a0,framesz($sp) # save a
sw $a3,framesz+12($sp) # save d
# x = g(b,c)
add $a0,$0,$a1 # put b in $a0
add $a1,$0,$a2 # put c in $a1
jal g # call g
sw $v0,framesz-8($sp) # put result in temp
# call g(d,e)
lw $a0,framesz+12($sp) # put d in $a0
lw $a1,framesz+16($sp) # put e in $a0
jal g # call g
# call g(x, g(d,e))
lw $a0,framesz-8($sp) # put temp in a0
add $a1,$0,$v0 # put prev function result in a1
jal g # call g
# add a to result
lw $t0,framesz($sp) # get a
add $v0,$v0,$t0 # add a to function result
# epilog
lw $ra,framesz-4($sp) # restore $ra
addiu $sp,$sp,framesz # pop frame
jr $ra # return
This is admittedly long,
but not terribly complicated if you take it one comment at a time.
A Simple Leaf Function
Consider the simple function
int g( int x, int y ) {
return (x + y);
}
This function does not call any other fuunction,
so it does not need to save $ra.
Also, it does not require any temporary storage.
Thus, it can be written with no stack manipulation at all.
Here it is:
g:
add $v0,$a0,$a1 # result is sum of args
jr $ra # return
That's all it takes.
|