Run-Time Storage Management
Every executing program has its own logical address space. Logical address space is partitioned into:
- Code: It is responsible for storing the executable target code.
- Static: It is used to holdglobal constant and compiler generate data.
- Heap: It is a dynamically managed area used to hold data objects.
- Stack: It is thedynamically managed area used to hold activation records.
The address in the target code can be described in two ways:
- Static Allocation
- Stack Allocation
In static allocation, the size and layout of the activation records are decided by the information stored in the symbol table. The activation record’s first location is used to store the return address. The three address code associated with code generation for simplified procedure call and return are the following:
- Action, a placeholder for the other statements.
The code that needs to implement static allocation is the following:
The following set of target-machine instructions can implement call callee statement:
ST callee.staticArea, #here + 20
callee.staticArea: It is a constant that represents the address of the starting point of the activation record for the callee.
callee.codeArea: It is a constant that represents the address of the first instruction for the called procedure.
# here + 20: It is a literalthatrepresents theaddress of the instruction.
A return statement can be implemented by the following code:
This code transfers control to the address saved at the beginning of the activation record for the callee.
HALT: It is the final instruction. This instruction returns control to the operating system.
ACTION: It is the set of machine instructions used to execute an action statement.
A static allocation can be converted into a stack allocation using relative addresses for storage in activation records. The position of the activation record for a procedure is not known in stack allocation until run-time. The activation record’s position is usually stored in a register, so words in the activation record can be accessed as offsets from the value.
The code to initialize the stack is as follows:
LD SP, # stackStart // initialize the stack
HALT // terminate execution
The code to implement a call statement in stack allocation is the following:
ADD SP, SP, #caller.recordSize // increment stack pointer
ST 0(SP), #here + 16 // Save return address
BR calee.codeArea // jump to the callee
#caller.recordSize: It represents the size of activation records.
#here + 16: It is the address of the instruction following BR.
The return statement consist of two parts:
BR *0(SP) // return to caller
SUB SP, SP, # caller.recordSize // Decrement stack pointer