next up previous
Next: Saving Registers Up: Procedures Previous: Passing Parameters on the

Functions

Procedures may alter parameter values which are passed by address. Some procedures produce an output value which is returned to the calling program separately from the parameters. A procedure that returns such a value is called a function.

In Pascal, a function value is returned by assigning a value to the name of the function in the definition of the function. For example, GetLargest(A, B, C) is a function which returns the largest of three parameters:

Function GetLargest(A, B, C: integer): integer;
{ Returns the largest of three integer parameters }
    var Largest: integer;
    begin { GetLargest }
        if (A > B) then
            Largest := A
        else
            Largest := B;
        if (C > Largest) then
            Largest := C;
        GetLargest := Largest;
    end;  { GetLargest }

In MAL there is no special instruction for returning a value. The function simply places the return value in registers $2-$3, also called $v0-$v1, or $f0-$f2. After returning from a function, the calling program must move the result to another register to prevent it from being overwritten by other function or procedure calls.

The following MAL program shows a function for returning the largest of three integer parameters which are passed to the function on the stack. The parameters are passed by value and the function returns the largest in register $2.

The MAL code to call the function and print the result is:

            .
            .
# assume the parameter values are in $t0-$t2
# push parameters on stack
        add     $sp, -12    # space for 3 parameters
        sw      $t0, 12($sp)
        sw      $t1, 8($sp)
        sw      $t2, 4($sp)
        jal     GetLargest  # call function
        add     $sp, 12     # pop parameters from stack
        move    $a0, $v0    # move result
        puti    $a0         # print result
            .
            .
# function returns largest of three parameters in $v0
GetLargest:     # no nested procedures; don't save $ra
# load the parameters from the stack
        lw      $a0, 4($sp)
        lw      $a1, 8($sp)
        lw      $a2, 12($sp)
# compare first and second parameters
        blt     $a0, $a1, secondlarger
        move    $v0, $a0    # first >= second
        b       compare:
secondlarger:
        move    $v0, $a1    # second > first
# compare third parameter
compare:
        bgt     $v0, $a2, done
        move    $v0, $a2    # third is largest
done:   jr      $ra         # return

Note that the function doesn't save its return address since it calls no other procedures.



CS301 Class Account
Mon Nov 25 11:40:41 AST 1996