123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376 |
- .bp
- .P1 "DATA ADDRESS SPACE"
- .PP
- The data address space is divided into three parts, called 'areas',
- each with its own addressing method:
- global data area,
- local data area (including the stack),
- and heap data area.
- These data areas must be part of the same
- address space because all data is accessed by
- the same type of pointers.
- .PP
- Space for global data is reserved using several pseudoinstructions in the
- assembly language, as described in
- the next paragraph and chapter 11.
- The size of the global data area is fixed per program.
- .QQ
- Global data is addressed absolutely in the machine language.
- Many instructions are available to address global data.
- They all have an absolute address as argument.
- Examples are LOE, LAE and STE.
- .PP
- Part of the global data area is initialized by the
- compiler, the
- rest is not initialized at all or is initialized
- with a value, typically \-32768 or 0.
- Part of the initialized global data may be made read-only
- if the implementation supports protection.
- .PP
- The local data area is used as a stack,
- which grows from high to low addresses
- and contains some data for each active procedure
- invocation, called a 'frame'.
- The size of the local data area varies dynamically during
- execution.
- Below the current procedure frame resides the operand stack.
- The stack pointer SP always points to the bottom of
- the local data area.
- Local data is addressed by offsetting from the local base pointer LB.
- LB always points to the frame of the current procedure.
- Only the words of the current frame and the parameters
- can be addressed directly.
- Variables in other active procedures are addressed by following
- the chain of statically enclosing procedures using the LXL or LXA instruction.
- The variables in dynamically enclosing procedures can be
- addressed with the use of the DCH instruction.
- .QQ
- Many instructions have offsets to LB as argument,
- for instance LOL, LAL and STL.
- The arguments of these instructions range from \-1 to some
- (negative) minimum
- for the access of local storage and from 0 to some (positive)
- maximum for parameter access.
- .PP
- The procedure call instructions CAL and CAI each create a new frame
- on the stack.
- Each procedure has an assembly-time parameter specifying
- the number of bytes needed for local storage.
- This storage is allocated each time the procedure is called and
- must be a multiple of the wordsize.
- Each procedure, therefore, starts with a stack with the local variables
- already allocated.
- The return instructions RET and RTT remove a frame.
- The actual parameters must be removed by the calling procedure.
- .PP
- RET may copy some words from the stack of
- the returning procedure to an unnamed 'function return area'.
- This area is available for 'READ-ONCE' access using the LFR instruction.
- The result of a LFR is only defined if the size used to fetch
- is identical to the size used in the last return.
- The instruction ASP, used to remove the parameters from the
- stack, the branch instruction BRA and the non-local goto
- instruction GTO are the only ones that leave the contents of
- the 'function return area' intact.
- All other instructions are allowed to destroy the function
- return area.
- Thus parameters can be popped before fetching the function result.
- The maximum size of all function return areas is
- implementation dependent,
- but should allow procedure instance identifiers and all
- implemented objects of type integer, unsigned, float
- and pointer to be returned.
- In most implementations
- the maximum size of the function return
- area is twice the pointer size,
- because we want to be able to handle 'procedure instance
- identifiers' which consist of a procedure identifier and the LB
- of a frame belonging to that procedure.
- .PP
- The heap data area grows upwards, to higher numbered
- addresses.
- It is initially empty.
- The initial value of the heap pointer HP
- marks the low end.
- The heap pointer may be manipulated
- by the LOR and STR instructions.
- The heap can only be addressed indirectly,
- by pointers derived from previous values of HP.
- .P2 "Global data area"
- .PP
- The initial size of the global data area is determined at assembly time.
- Global data is allocated by several
- pseudoinstructions in the EM assembly
- language.
- Each pseudoinstruction allocates one or more bytes.
- The bytes allocated for a single pseudo form
- a 'block'.
- A block differs from a fragment, because,
- under certain conditions, several blocks are allocated
- in a single fragment.
- This guarantees that the bytes of these blocks
- are consecutive.
- .PP
- Global data is addressed absolutely in binary
- machine language.
- Most compilers, however,
- cannot assign absolute addresses to their global variables,
- especially not if the language
- allows programs to be composed of several separately compiled modules.
- The assembly language therefore allows the compiler to name
- the first address of a global data block with an alphanumeric label.
- Moreover, the only way to address such a named global data block
- in the assembly language is by using its name.
- It is the task of the assembler/loader to
- translate these labels into absolute addresses.
- These labels may also be used
- in CON and ROM pseudoinstructions to initialize pointers.
- .PP
- The pseudoinstruction CON allocates initialized data.
- ROM acts like CON but indicates that the initialized data will
- not change during execution of the program.
- The pseudoinstruction BSS allocates a block of uninitialized
- or identically initialized
- data.
- The pseudoinstruction HOL is similar to BSS,
- but it alters the meaning of subsequent absolute addressing in
- the assembly language.
- .PP
- Another type of global data is a small block,
- called the ABS block, with an implementation defined size.
- Storage in this type of block can only be addressed
- absolutely in assembly language.
- The first word has address 0 and is used to maintain the
- source line number.
- Special instructions LIN and LNI are provided to
- update this counter.
- A pointer at location 4 points to a string containing the
- current source file name.
- The instruction FIL can be used to update the pointer.
- .PP
- All numeric arguments of the instructions that address
- the global data area refer to locations in the
- ABS block unless
- they are preceded by at least one HOL pseudo in the same
- module,
- in which case they refer to the storage area allocated by the
- last HOL pseudoinstruction.
- Thus LOE 0 loads the zeroth word of the most recent HOL, unless no HOL has
- appeared in the current file so
- far, in which case it loads the zeroth word of the
- ABS fragment.
- .PP
- The global data area is highly fragmented.
- The ABS block and each HOL and BSS block are separate fragments.
- The way fragments are formed from CON and ROM blocks is more complex.
- The assemblers group several blocks into a single fragment.
- A fragment only contains blocks of the same type: CON or ROM.
- It is guaranteed that the bytes allocated for two consecutive CON pseudos are
- allocated consecutively in a single fragment, unless
- these CON pseudos are separated in the assembly language program
- by a data label definition or one or more of the following pseudos:
- .DS
- ROM, BSS, HOL and END
- .DE
- An analogous rule holds for ROM pseudos.
- .P2 "Local data area"
- .PP
- The local data area consists of a sequence of frames, one for
- each active procedure.
- Below the frame of the current procedure resides the
- expression stack.
- Frames are generated by procedure calls and are
- removed by procedure returns.
- A procedure frame consists of six 'zones':
- .DS
- 1. The return status block
- 2. The local variables and compiler temporaries
- 3. The register save block
- 4. The dynamic local generators
- 5. The operand stack.
- 6. The parameters of a procedure one level deeper
- .DE
- A sample frame is shown in Figure 1.
- .PP
- Before a procedure call is performed the actual
- parameters are pushed onto the stack of the calling procedure.
- The exact details are compiler dependent.
- EM allows procedures to be called with a variable number of
- parameters.
- The implementation of the C-language almost forces its runtime
- system to push the parameters in reverse order, that is,
- the first positional parameter last.
- Most compilers use the C calling convention to be compatible.
- The parameters of a procedure belong to the frame of the
- calling procedure.
- Note that the evaluation of the actual parameters may imply
- the calling of procedures.
- The parameters can be accessed with certain instructions using
- offsets of 0 and greater.
- The first byte of the last parameter pushed has offset 0.
- Note that the parameter at offset 0 has a special use in the
- instructions following the static chain (LXL and LXA).
- These instructions assume that this parameter contains the LB of
- the statically enclosing procedure.
- Procedures that do not have a dynamically enclosing procedure
- do not need a static link at offset 0.
- .PP
- Two instructions are available to perform procedure calls, CAL
- and CAI.
- Several tasks are performed by these call instructions.
- .QQ
- First, a part of the status of the calling procedure is
- saved on the stack in the return status block.
- This block should contain the return address of the calling
- procedure, its LB and other implementation dependent data.
- The size of this block is fixed for any given implementation
- because the lexical instructions LPB, LXL and LXA must be able to
- obtain the base addresses of the procedure parameters \fBand\fP local
- variables.
- An alternative solution can be used on machines with a highly
- segmented address space.
- The stack frames need not be contiguous then and the first
- status save area can contain the parameter base AB,
- which has the value of SP just after the last parameter has
- been pushed.
- .QQ
- Second, the LB is changed to point to the
- first word above the local variables.
- The new LB is a copy of the SP after the return status
- block has been pushed.
- .QQ
- Third, the amount of local storage needed by the procedure is
- reserved.
- The parameters and local storage are accessed by the same instructions.
- Negative offsets are used for access to local variables.
- The highest byte, that is the byte nearest
- to LB, has to be accessed with offset \-1.
- The pseudoinstruction specifying the entry point of a
- procedure, has an argument that specifies the amount of local
- storage needed.
- The local variables allocated by the CAI or CAL instructions
- are the only ones that can be accessed with a fixed negative offset.
- The initial value of the allocated words is
- not defined, but implementations that check for undefined
- values will probably initialize them with a
- special 'undefined' pattern, typically \-32768.
- .QQ
- Fourth, any EM implementation is allowed to reserve a variable size
- block beneath the local variables.
- This block could, for example, be used to save a variable number
- of registers.
- .QQ
- Finally, the address of the entry point of the called procedure
- is loaded into the Program Counter.
- .PP
- The ASP instruction can be used to allocate further (dynamic)
- local storage.
- The base address of such storage must be obtained with a LOR~SP
- instruction.
- This same instruction ASP may also be used
- to remove some words from the stack.
- .PP
- There is a version of ASP, called ASS, which fetches the number
- of bytes to allocate from the stack.
- It can be used to allocate space for local
- objects whose size is unknown at compile time,
- so called 'dynamic local generators'.
- .PP
- Control is returned to the calling procedure with a RET instruction.
- Any return value is then copied to the 'function return area'.
- The frame created by the call is deallocated and the status of
- the calling procedure is restored.
- The value of SP just after the return value has been popped must
- be the same as the
- value of SP just before executing the first instruction of this
- invocation.
- This means that when a RET is executed the operand stack can
- only contain the return value and all dynamically generated locals must be
- deallocated.
- Violating this restriction might result in hard to detect
- errors.
- The calling procedure has to remove the parameters from the stack.
- This can be done with the aforementioned ASP instruction.
- .PP
- Each procedure frame is a separate fragment.
- Because any fragment may be placed anywhere in memory,
- procedure frames need not be contiguous.
- .Dr 47
- |===============================|
- | actual parameter n-1 |
- |-------------------------------|
- | . |
- | . |
- | . |
- |-------------------------------|
- | actual parameter 0 | ( <\- AB )
- |===============================|
- |===============================|
- |///////////////////////////////|
- |///// return status block /////|
- |///////////////////////////////| <\- LB
- |===============================|
- | |
- | local variables |
- | |
- |-------------------------------|
- | |
- | compiler temporaries |
- | |
- |===============================|
- |///////////////////////////////|
- |///// register save block /////|
- |///////////////////////////////|
- |===============================|
- | |
- | dynamic local generators |
- | |
- |===============================|
- | operand |
- |-------------------------------|
- | operand |
- |===============================|
- | parameter m-1 |
- |-------------------------------|
- | . |
- | . |
- | . |
- |-------------------------------|
- | parameter 0 | <\- SP
- |===============================|
- .Df
- Figure 1. A sample procedure frame and parameters.
- .De
- .P2 "Heap data area"
- .PP
- The heap area starts empty, with HP
- pointing to the low end of it.
- HP always contains a word address.
- A copy of HP can always be obtained with the LOR instruction.
- A new value may be stored in the heap pointer using the STR instruction.
- If the new value is greater than the old one,
- then the heap grows.
- If it is smaller, then the heap shrinks.
- HP may never point below its original value.
- All words between the current HP and the original HP
- are allocated to the heap.
- The heap may not grow into a part of memory that is already allocated.
- When this is attempted, the STR instruction will cause a trap to occur.
- In this case, HP retains its old value.
- .PP
- The only way to address the heap is indirectly.
- Whenever an object is allocated by increasing HP,
- then the old HP value must be saved and can be used later to address
- the allocated object.
- If, in the meantime, HP is decreased so that the object
- is no longer part of the heap, then an attempt to access
- the object is not allowed.
- Furthermore, if the heap pointer is increased again to above
- the object address, then access to the old object gives undefined results.
- .PP
- The heap is a single fragment.
- All bytes have consecutive addresses.
- No limits are imposed on the size of the heap as long as it fits
- in the available data address space.
|