4. External and Internal Symbols

Part of the SMAL Manual
by Douglas W. Jones
THE UNIVERSITY OF IOWA Department of Computer Science


  1. External Declarations
  2. Internal Declarations
  3. Common Declarations

SMAL32 allows the results of assembling a number of source programs to be combined into a single program at run-time by a linkage editor. Because of this, there are two classes of symbols in SMAL, local symbols and global symbols. Local symbols are defined only within one particular source program, and the same name may be used with a different meaning within another. Global symbols, on the other hand, are shared by all programs which are to be linked into one final program. There are two kinds of global symbols: Those which are defined internally in one program and referenced in another, and those which are not defined in any particular file but are expected to be defined by the linker.


4.1. External Declarations

When a symbol defined in one program is to be referenced by another program, it must be declared as being external to the program which uses it. This is done by defining that identifier with an external directive:

<symbolic directive> ::= EXT <identifier> { , <identifier> }
Identifiers which are declared as external symbols may not be used as labels and they may not have values assigned to them; violation of this rule will result in a "multiple label definition" error. Identifiers used in this context must not have been previously referenced in the text of the program; a "name used before defined" error will result when this rule is violated. Multiple identifiers may be declared with one EXT directive.

In addition to relocatable symbols introduced by defining labels in terms of relocatable location counter values, each external symbol introduces a new relocation base relative to which additional symbols may be defined. Thus, it is legal to add or subtract absolute values to or from an external symbol name in order to reference adjacent values (if the name is externally defined as a label, the adjacent values will reference adjacent memory locations). The following fragment of a SMAL32 assembler listing illustrates the use of external declarations:

                             7        EXT EXT
                             8    ADR = EXT + 8
+000000:+00000000            9        W EXT
+000004:+00000008           10        W ADR
Note that the external symbol "EXT" in the above example is used as a relocation base for the symbol "ADR".


4.2. Internal Declarations

When a program wishes to allow other programs to reference a locally defined symbol, it must be declared to be accessible by an internal directive:

<symbolic directive> ::= INT <identifier> { , <identifier> }

Identifiers declared as internal must be defined somewhere in the program; failure to follow this rule will result in an "undefined symbol" error. Within the program where an internal symbol is defined, that symbol may be manipulated as if it were an entirely local symbol. The value of that symbol at the end of the second assembly pass will be the value which is exported. Multiple identifiers may be declared by one INT directive. The following fragment of legal SMAL32 code illustrates the use of internal directives:

          INT EXT
          INT CONST, CONST1
    EXT:  CONST = 5
          CONST1 = 6

Note that the internal symbol "EXT" is declared as a label, so it probably has a relocatable value, but the internal symbol "CONST" is declared by assigning an absolute integer value to it.


4.3. Common Declarations

When a program wishes to reference an area of memory which is to be allocated by the linkage editor, that area must be declared to be a common block and its size must be specified:

<symbolic directive> ::= COMMON <identifier> , <expression>

Common names may be used exactly like any external symbol, and must satisfy the same rules. Thus, the name must not have been referenced previous to the common directive, and it must not be defined anywhere else in the program.

The second argument to the common directive gives the minimum size of the region which the linkage editor is expected to allocate. This must be either an absolute value, in bytes, or it must be relocated relative to the common base; any other form will result in a "misuse of relocation" error. Generally, the declarations of the same common in the different programs linked by the linker should be the same. If different sizes are specified, the first size encountered by the linker will be used and later sizes will be ignored.

The size specified is the minimum size for two reasons: First, the size may be overridden at linkage time, when a larger size may be specified. Second, the size will be rounded up to an even number of 32 bit words in order to guarantee that all common blocks are aligned by the linker.

The following fragment of an assembler listing illustrates the correct use of the COMMON directive:

                            11    COMMON COM1,6
                            12    COMMON COM2,COM2LIM
                            13    LOCSAVE = .
                            14    . = COM2
+000000:+00000000           15    W COM1
+000004: 00000006           16    W 6
                            17    COM2LIM:
                            18    . = LOCSAVE

Note that the size of "COM1" above is declared with a simple absolute value, but that the size of "COM2" is declared by using a label relocated relative to "COM2" itself. The pattern of code used to initialize "COM2" is suggested as a standard for assembly time initialization of commons.