# Class 25: More Stack Frames

Back to Stack Frames. On to Symbol Tables.

Held Friday, November 1, 2002

Summary

Today we continue our investigation of stack frames by considering some particular examples.

Notes

Overview

## An Example

• Let us continue our discussion of stack frames with a simple example.
• Everyone's favorite recursive procedure is `factorial`, so we'll try that first.
• I've written slightly more explicit code than is normal to help you think about what is happening.
```function factorial(n: integer): integer;
var
tmp1: integer;
begin
if (n = 0) then
factorial := 1
else
begin
tmp := factorial(n-1);
factorial := n * tmp;
end
end;
```
• What will the stack frame for this procedure look like? Here's one simple possibility (along with an indication as to where we hope to have the frame pointer and stack pointer, assuming stacks grow downward):
```+--------------+  <- FP
|   old FP     |
+--------------+
| return value |
+--------------+
+--------------+
|      n       |
+--------------+  <- SP
```
• We'll assume that the local procedure immediately pushes room for two temporaries, giving us the following stack.
```+--------------+  <- FP
|   old FP     |
+--------------+
| return value |
+--------------+
+--------------+
|      n       |
+--------------+
|     tmp      |
+--------------+
|    extra     |
+--------------+  <- SP
```
• After a recursive call finishes, we expect to have
```+--------------+  <- FP
|   old FP     |
+--------------+
| return value |
+--------------+
+--------------+
|      n       |
+--------------+
|     tmp      |
+--------------+
|    extra     |
+--------------+  <- SP
|   our FP     |
+--------------+
| rec. result  |
+--------------+
```
• What does the assembly code for `factorial` look like? In a generic language with four bytes per word
```BEGIN_FACTORIAL:
# Do anything appropriate for the beginning of a procedure call
...
# if (n = 0)
START_FACTORIAL_CODE:
PUSH 8			  # Space for temps
COMPARE MEM[FP+12], CONSTANT[0]
JUMP IF EQUAL BASE_CASE
JUMP RECURSIVE_CASE
# factorial := 1
BASE_CASE:
STORE INTO MEM[FP+4] FROM CONSTANT[1]
JUMP END_FACTORIAL
# tmp := factorial(n-1)
RECURSIVE_CASE:
# Compute n-1
SUBTRACT CONSTANT[1] FROM MEM[FP+12], STORE IN MEM[SP-8]
# Call factorial
...
# Copy the value back
STORE INTO MEM[SP-8] FROM MEM[SP+4]
# factorial := n * tmp
MULTIPLY MEM[SP-12] BY MEM[SP-8], STORE IN MEM[FP+4]
JUMP END_FACTORIAL
# Clean up
END_FACTORIAL:
...
```
• Okay, what do we have to do at the beginning of a procedure? If a procedure knows how much local memory it needs, the procedure should increment the stack pointer
```# Do anything appropriate for the beginning of a procedure call
```
• At the end, the procedure should undo what it just did.
```END_FACTORIAL:
SUBTRACT CONSTANT[8] from SP
```
• It needs to restore the frame pointer
```  SET FP to MEM[FP]
```
• It also needs to return to the place that it started.
```  JMP MEM[FP+8]
```
• Now to the hard part. What do we do for a recursive procedure call?
• Before jumping to the code for the procedure, we need to store the parameter.
```  STORE INTO MEM[SP+12] FROM MEM[SP-8]
```
• We may update the frame pointer, so we store it in the next frame.
```  STORE INTO MEM[SP] FROM FP
```
• We also need to update the frame pointer. (We assume that procedures update their own stack pointers.) Conveniently, the end of one frame (given by the stack pointer) is the same as the beginning of the next frame (given by the frame pointer).
```  SET FP to SP
```
• We have to advance the stack pointer beyond the pushed stuff
```  ADD CONSTANT[16] to SP
```
```  STORE INTO MEM[SP+8], RETURN_HERE
```
• We need to call the procedure. Generically,
```  JUMP BEGIN_FACTORIAL
RETURN_HERE:
```
• We need to recover from the procedure. That means that we need to update the stack pointer to where it was before.
```  SUBTRACT CONSTANT[16] from SP
```
• We'll go through an example (and work out the kinks) in class.

## History

Thursday, 29 August 2002

• First version, based somewhat on outlines from CS362 2001S.

Back to Stack Frames. On to Symbol Tables.

Disclaimer: I usually create these pages on the fly, which means that I rarely proofread them and they may contain bad grammar and incorrect details. It also means that I tend to update them regularly (see the history for more details). Feel free to contact me with any suggestions for changes.

This document was generated by Siteweaver on Fri Dec 6 10:38:24 2002.
The source to the document was last modified on Wed Sep 4 10:08:36 2002.
This document may be found at `http://www.cs.grinnell.edu/~rebelsky/Courses/CS362/2002F/Outlines/outline.25.html`.

You may wish to validate this document's HTML ; ; Check with Bobby

Glimmer Labs: The Grinnell Laboratory for Interactive Multimedia Experimentation & Research
glimmer@grinnell.edu