The power function, which raises a number B to a positive integer power N is defined by:
where
indicates multiplication. A Pascal function may be
written using a loop to evaluate the product iteratively:
Function Power(N, B: integer): integer;
{ Calculates B to Nth power iteratively }
var I, Product: integer;
begin { Power }
Product := 1
for I := 1 to N do
Product := Product * B;
Power := Product;
end; { Power }
Note that the product calculated in the procedure is returned by assigning Product to Power, the name of the function.
The same function may be defined recursively as:
In Pascal, the recursive power function can be written as:
Function Power(N, B: integer): integer;
{ Calculates B to Nth power recursively }
begin { Power }
if (N <= 0) then
Power := 1
else
Power := B * Power(N-1,B);
end; { Power }
To implement the Power procedure in MAL, the nested procedure techniques for saving registers (including $ra) and parameters must be used.
Suppose the Power function has two parameters, N and B, which are passed on the stack and the function returns its result in $v0. Assume that the parameters N and B are initially in registers $a0 and $a1, respectively.
The MAL code to call the function and print the result is:
.
.
add $sp, -8 # push N and B on stack
sw $a0, 4($sp)
sw $a1, 8($sp)
jal Power # call procedure
add $sp, 8 # pop parameters
move $4, $2 # move result for printing
puti $4 # print function result
The function below implements a recursive Power function. When the function calls itself recursively, it must follow the established conventions for passing parameters on the stack:
# function to calculate B to the Nth power recursively
# returns: $v0
# parameters: B (on stack)
# N (on stack)
# registers: $a0 -- N
# $a1 -- B
Power: sw $ra, ($sp) # save return address on stack
add $sp, -4
lw $a0, 8($sp) # load N from stack
lw $a1, 12($sp) # load B from stack
bgtz $a0, Induct # if N>0, recursive case
li $v0, 1 # base case: return(1)
b Return
Induct: # recursive case
sub $a0, 1 # N <- N-1
add $sp, -8 # push N and B on stack
sw $a0, 4($sp)
sw $a1, 8($sp)
jal Power # call Power(N-1, B)
add $sp, 8 # pop parameters
lw $a1, 12($sp) # restore B
mul $v0,$v0,$a1 # return(B*Power(N-1, B))
Return: add $sp, 4 # restore return address
lw $ra, ($sp)
jr $ra # return
Any recursive algorithm can be implemented iteratively and vice-versa. Nonrecursive algorithms are usually faster because they doesn't have the overhead of the recursive procedure calls.