ECE/CS 314: Computer Organization
Fall 2003
Calling Conventions
 
 
 

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.
  Questions?
   
 
Contact Alan Demers