| Technical Information

Previous | The A68k Assembler | Next

The actual symbol table entries (pointed to by the hash table, colliding entries are linked together) are stored in 8K chunks which are allocated as required. The first entry of each chunk is reserved as a link to the next chunk (or NULL in the last chunk) - this makes it easy to find all the chunks to free them when we're finished. All symbol table entries are stored in pass 1. During pass 2, cross- reference table entries are built in the same group of chunks, immediately following the last symbol table entry. Additional chunks will continue to be linked in if necessary.
Symbol names and macro text are stored in another series of linked chunks. These chunks consist of a link pointer followed by strings (terminated by nulls) laid end to end. Symbols are independent entries, linked from the corresponding symbol table entry. Macros are stored as consecutive strings, one per line - the end of the macro is indicated by an `ENDM` statement. If a macro spans two chunks, the last line in the original chunk is followed by a newline character to indicate that the macro is continued in the next chunk.
Relocation information is built during pass 2 in yet another series of linked chunks. If more than one chunk is needed to hold one section's relocation information, all additional chunks are released at the end of the section.
The secondary heap is built from both ends, and it grows and shrinks according to how many macros and `INCLUDE` files are currently open. At all times there will be at least one entry on the heap, for the original source code file. The expression parser also uses the secondary heap to store its working stacks - this space is freed as soon as an expression has been evaluated.
The bottom of the heap holds the names of the source code file and any macro or `INCLUDE` files that are currently open. The full path is given. A null string is stored for user macros. Macro arguments are stored by additional strings, one for each argument in the macro call line. All strings are stored in minimum space, similar to the labels and user macro text on the primary heap. File names are pointed to by the fixed table entries (see below) - macro arguments are accessed by stepping past the macro name to the desired argument, unless NARG would be exceeded.
The fixed portion of the heap is built down from the top. Each entry occupies 16 bytes. Enough information is stored to return to the proper position in the outer file once the current macro or `INCLUDE` file has been completely processed.
The diagram below illustrates the layout of the secondary heap.

    Heap2 + maxheap2 ----------->  ___________________________
                                  |                           |
                                  |   Input file table        |
    struct InFCtl *InF ---------> |___________________________|
                                  |                           |
                                  |   Parser operator stack   |
    struct OpStack *Ops --------> |___________________________|
                                  |                           |
                                  |   (unused space)          |
    struct TermStack *Term -----> |___________________________|
                                  |                           |
                                  |   Parser term stack       |
    char *NextFNS --------------> |___________________________|
                                  |                           |
                                  |   Input file name stack   |
    char *Heap2 ----------------> |___________________________|

The "high-water mark" for `NextFNS` is stored in `char *High2`, and the "low-water mark" (to stretch a metaphor) for `InF` is stored in `struct InFCtl *LowInF`. These figures are used only to determine the maximum heap usage.