Upload
annabelle-wiggins
View
220
Download
5
Embed Size (px)
Citation preview
Procedures – Generating the Code
Lecture 21
Mon, Apr 4, 2005
Code for a FUNC Syntax Tree
The code generated by a FUNC syntax tree should output the text
.text
.globl _fname
.def _fname; .scl 2; .type 32; .endef
_fname:
which the assembler uses to define the function name _fname.
Code for a FUNC Syntax Tree
A FUNC syntax tree must also Save the old base pointer. Save the old stack pointer. Create the local block.
The code should bepush %ebp # Save base ptr
mov %esp,%ebp # Save stack ptr
sub $n,%esp # n bytes for locals
Code for a FEND Syntax Tree
The code generated by a FEND syntax tree should Restore the old stack pointer (thereby clearing the
local block). Restore the old base pointer. Return to the calling function.
The code should bemov %ebp,%esp # Restore stack ptrpop %ebp # Restore base ptrret # Return
Code for a RET Syntax Tree
The code for a return is similar to the code for the end of a function, except There is a return value. The block level should not be changed.
If the return value is an integer, it should be placed in register eax. Why not push it onto the stack?
If the return value is a double, it should be placed (or left) in FPU register st(0).
Code for a CALL Syntax Tree
Function calls are a bit more complicated since we must process the LIST tree.
We must push onto the stack each parameter in the LIST tree.
If we do a pre-order traversal, pushing as we go, in which order will the parameters be pushed?
Code for a CALL Syntax Tree
First, we must distinguish the three cases: No parameter. One parameter. More than one parameter.
What distinguishes the case of no parameter?
What distinguishes the case of exactly one parameter?
Anything else must be more than one parameter and will be handled recursively.
Code for a CALL Syntax Tree
If the right subtree is null, then there is no parameter.
If the right subtree is not a LIST tree, then it must be an expression tree representing one parameter. Push that parameter onto the runtime stack.
If the right subtree is a LIST tree, then call on generateNodeCode() to handle it under the LIST case.
Code for a CALL Syntax Tree
Incidentally, the CALL node may be either unary or binary.
It is listed in the Utility class as binary. Therefore, when a CALL tree is printed, we
will get the warning “attempted to print a null tree.”
We may ignore it or we can prevent it by making CALL a special case.
Code for a LIST Syntax Tree
While processing the parameter list, we must count the total number of bytes used by the parameters.
Call this paramBlockSize. Before processing any parameters,
The current value of paramBlockSize should be pushed onto a stack since a parameter list may include a function call itself.
paramBlockSize should be set to 0.
Code for a LIST Syntax Tree
In the LIST case, we simply do right-to-left pre-order traversal of the tree, pushing the parameters as we go.
Each parameter is an expression, so we must call on traverseTree() to do a left-to-right post-order traversal of the expression tree.
Pseudocode for the LIST Case
Call traverseTree() to handle the right subtree as an expression tree. Push the value onto the runtime stack.
If the left subtree is a LIST tree, then Call generateNodeCode() to handle it
recursively as a LIST tree. (Recursive case) Else
Call traverseTree() to handle it as an expression tree. (Non-recursive case) Push the value onto the runtime stack.
Code for a CALL Syntax Tree
Now, back to the CALL case. We still have to
Do the call instruction Clear the parameters off the stack. Pass the return value back.
The call instruction is of the form
call _fname The name is stored in the left subtree.
Code for a CALL Syntax Tree
To “clear” the parameters off the stack, we simply move the stack pointer. Add to the stack pointer the number of bytes
occupied by the parameters. That value has been stored on the special stack
designated for that purpose. Pop the number off the stack. Use it to adjust the stack pointer.
Code for a CALL Syntax Tree
If the return value is a double, it is already in st(0), where it belongs.
If it is a int, then it is on the stack and must be popped into eax.