Files
2025-02-Compiler/notes/6.md

69 lines
1.7 KiB
Markdown

# Code Generation 1
## Organization of Storage
* Code Area
* Static Area
* Stack Area
* Heap Area
### Stack Management using Register File
* Stack pointer (SP): points to the top of the frame
* Frame Pointer (FP, BP): points to the frame base
because stack frame size is not always known at compile time.
### Saving Registers
The callee may overwrite useful values in the registers.
So caller's useful values should be stored in stack when function-call (`push`), and restored when callee return (`pop`). This role is done by both callee and caller (`caller-saved`, `callee-saved`).
* Caller-saved registers
used to hold **temporary quantities** that need not be preserved across calls.
* Callee-saved registers
used to hold **long-lived values** that should be preserved across calls.
So Code before call:
* push the params.
* push caller-saved registers
* push return address (curr `PC`) and jump to callee code
Prologue of callee
* push dynamic link (`FP`)
* old stack pointer becomes new frame pointer
* push callee-saved registers
* push local var
Epilogue
* pop callee-saved registers
* store return value at appropriate place
* restore old stack pointer
* pop old frame pointer
* pop return addr and jump to that
Code after call
* pop caller-saved registers
* use return value from appropriate place
When accessing stack variable, use offsets from `FP`.
## Global Variables or Static Variables
Global variables have same references for all scope. They are assigned a **fixed address once** (**statically allocated**).
`Code > Static Data > Stack`
## Dynamic Allocation
The dynamically allocated value outlives the procedure creating it (unless deleted).
`Code > Static Data > Stack -> <- Heap`