CSE 30 -- Lecture 8 -- Oct 22


In this lecture, I gave the following algorithm for exponentiation, in a C-like pseudo-code:
exp(x,y)
{
	if (y == 0) return 1.0;	/* 00 indefinite, but returns 1 */
	if (y odd) return x * exp(x2,(y-1)/2);
	return exp(x2,y/2);
}

I proved this algorithm correct (modulo overflows) using induction on the length of the exponent in bits. The precondition is that y is non-negative.

Base case: |y| = 1. So y = 0 or y = 1 holds. First case: y = 0. exp(x,0) returns 1.0, which is what we wanted. Next case: y = 1. For exp(x,1), the code returns x * exp(x2,0) = x, which is what we wanted. The base case is correct.

Induction step: Assume that exp(x,y) returns the correct value (xy) when |y| <= k. We want to prove that exp(x,y) is correct when |y| = k+1. Let y be a non-negative number where |y|=k+1. We express it as

y = 2 * z + y0
where y0 is either 0 or 1 (the low order bit in the binary representation of y).

Now we note that z is a k bit number. Thus, exp(x2,z) will be computed correctly, yielding x2z. So, suppose y is odd. Then y0 is 1, and the code returns

x * exp(x2,(y-1)/2)
= x * exp(x2,z)
= x * x2z
= x2z+1
= xy
which is what we wanted. Next, suppose y is even. Then y0 is 0, and the code uses the last statement to return
exp(x2,y/2)
= exp(x2,z)
= x2z
= xy
which is the correct answer.

This completes the induction, so exp(x,y) will return the correct value for all x and y where y is non-negative, and the computation does not overflow (the abstract algorithm never overflows, but implementations may).

To implement the recursive version of exp, we need to be able to do the recursion. Because the $ra register is modified by the jal instruction, each recursive instance of exp must save its $ra prior to recursively calling itself with modified parameters. This is saved in the stack within a stack frame.

First, the stack pointer. The stack pointer ($sp) contains the address of the first free word of memory. Above the stack pointer (addresses greater than the stack pointer) are memory locations used by other routines. Below the stack pointer are memory that has not yet been claimed. To allocate temporary memory for a function, the stack pointer is simply decremented the appropriate amount.

The frame pointer is another register which is used to make it easy to refer to the stack frame's contents and to arguments to the function (beyond those that are in $a0 -- $a3). Different compilers use different conventions: the C compiler from SGI/MIPS does not use a frame pointer, but the GNU C compiler does. In any case, always treat $fp as a caller-saved register, and code generate by either compiler will work.

Compilers insert prologue and epilogue instructions before and after the assembly code that correspond to the original C or C++ source code. The prologue's job is to allocate stack space and save whichever registers need to be saved, and the epilogue's job is to restore those registers to their previous values and deallocate stack space. One example prologue/epilogue was given in class:

fn:	sub $sp,$sp,8
	sw $fp,4($sp)
	add $fp,$sp,8
	sw $ra,0($fp)
	... body of program ...
	lw $ra,0($fp)
	lw $fp,4($sp)
	add $sp,$sp,8
	jr $ra
Another is the following, which works with alloca:
fn:	sub $sp,$sp,8
	sw $fp,4($sp)
	add $fp,$sp,8
	sw $ra,0($fp)
	... body of program ...
	lw $ra,0($fp)
	move $t0,$fp
	lw $fp,-4($fp)
	move $sp,$t0
	jr $ra
Note that we could save an instruction in the epilogue:
	lw $ra,0($fp)
	move $sp,$fp
	lw $fp,-4($fp)
	jr $ra
but this is potentially unsafe if the program is interrupted by a signal between the second and third instruction in the epilogue: interrupts assume that anything below the stack is unused (and therefore could be allocated and overwritten), but this code sequence relies on -4($fp) remaining untouched (since $fp == $sp, we know that -4($fp) is below the stack pointer).

Space for saving the $t and $s scratch registers and for holding local variables are also kept in the stack frame. Instead of 8 bytes (2 words), the prologue and epilogue code would just allocate enough space for everything.


[ CSE home | CSE talks | bsy's home page | webster i/f | yahoo | lycos | altavista | pgp key svr | spam | commerce ]
picture of bsy

bsy@cse.ucsd.edu, last updated Sun Oct 26 23:14:30 PST 1997.

email bsy


Don't make me hand over my privacy keys!