one pass with fixup one-pass structure definition must occur before any uses (that is, uses can have...
TRANSCRIPT
One Pass with Fixup
One-pass structure• definition must occur before any uses (that is, uses can
have only backward references to definitions)
examples: macro definition before macro calls
variable declarations before uses
One Pass with Fixup
Two-pass structure• uses can have forward or backward references to
definitions• first pass collects the definitions into a table (e.g., symbol
table)• second pass accomplishes the translation by consulting
the definition table whenever a use is encountered• only the table is required to remain in memory; the
source file can be read from disk twice
example: traditional assembler
One Pass with Fixup
One-pass with fixup structure
• also known as back-patching
• the translated code as well as the definition table both need to be kept in memory
• algorithm for assembler
label(x) // x defined at location 10 ... blt0(y) // y used at location 15 ... beq0(y) // y used at location 20 ... label(y) // y defined at location 25
One Pass with Fixup
One-pass with fixup structure
In one-pass-with-fixup, the symbol table needs a third field (in addition to the symbol name and address fields). The third field indicates whether the symbol is defined or undefined.
One Pass with Fixup
One-pass with fixup structure
When you encounter the use of a symbol, perform a lookup in the symbol table:
a) if the symbol is defined, use the address value from the entry
b) if the symbol is not yet present, add an entry for this symbol and mark it as undefined; use the address field in the entry as a pointer to a linked list of use locations for this undefined symbol and add the address of the current word to the first node,
One Pass with Fixup
One-pass with fixup structure
When you encounter the use of a symbol, perform a lookup in the symbol table:
a) if the symbol is defined, use the address value from the entry
One Pass with Fixup
. . .
x def 10
. . .
y undef <head>
. . .
15 NULL
use-location node
b) if the symbol is not yet present, add an entry for this symbol and mark it as undefined; use the address field in the entry as a pointer to a linked list of use locations for this undefined symbol and add the address of the current word to the first node,
One Pass with FixupOne-pass with fixup structure
c) if the symbol is present but undefined, add another node to the linked list with the address of the current word in that node, e.g.,
. . .
y undef <head> 20 <next> 15 NULL
. . .
Note that you can extend the use-location nodes to contain an indicator for what type of fixup is needed, e.g., full-word value, high 22 bits, low 10 bits, etc.
One Pass with Fixup
When you encounter the definition of a symbol, perform a lookup in the symbol table:
a) if the symbol is already defined, you have encountered a "multiple definition" error
b) if the symbol is not yet present, add an entry for this symbol land mark it as defined; use the current value of the location counter as the address
One Pass with Fixup
. . .
x def 10
. . .
y def 25
. . .
b) if the symbol is present but undefined, "fix up" or "back patch" all the undefined uses by traversing the linked list and storing the current value of the location counter into the memory words identified in the nodes of the list; then free the list and mark the symbol as defined using the current value of the location
c) symbol type address
One Pass with Fixup
When you reach the end of the assembly language program, scan the symbol table for any remaining undefined entries. These are either errors or, absent a requirement to explicitly mark the use of external names, these are symbols that must be passed to the linker to be resolved.
To visualize this, consider the actions of the assembler as it moves through a posible source program:
One Pass with Fixupstart translation
... ... use x ... // forward reference - insert "x" into the // symbol table as an undefined symbol and // start a linked list of use locations ... ... use x ... // forward reference - add this use location // to the linked list ... ... define x ... // traverse the linked list and fixup all // forward references with the value of the // definition, then mark "x" as a defined // symbol and store the defining value ... ... use x ... // backward reference - resolve by table lookup ... ... define x ... // multiply-defined symbol error! ... end translation // check for undefined symbols
One Pass with Fixup
Numeric local labels in a two-pass structure (a relaxation of the prohibition on multiply-defined symbols)
(adapted from the GNU description)
Local labels help programmers use names temporarily. They are numeric symbols that can be redefined at various points in a program, but each valid use of a local label has a unique definition to which it refers. To define a local label for our chapter 1 assemblers, write a label with a number <N>
label(<N>)
To refer to the most recent previous definition of that symbol write <N>b, using the same number as when you defined the label. To refer to the next definition of a local label, write <N>f. The "b" stands
for "backward", and the "f" stands for "forward". Prior to the first
definition of label <N>, the reference <N>b is undefined; likewise,
after the last definition of label <N>, the reference <N>f is undefined.
Numeric local labels in a two-pass structure
(a relaxation of the prohibition on multiply-defined symbols)
(adapted from the GNU description)
Local labels help programmers use names temporarily. They are numeric symbols that can be redefined at various points in a program, but each valid use of a local label has a unique definition to which it refers. To define a local label for our chapter 1 assemblers, write a label with a number <N>
label(<N>)
To refer to the most recent previous definition of that symbol write <N>b, using the same number as when you defined the label. To refer to the next definition of a local label, write <N>f. The "b" stands for "backward", and the "f" stands for "forward".
Numeric local labels in a two-pass structure
• Prior to the first definition of label <N>, the reference <N>b is undefined; likewise, After the last definition of label <N>, the reference <N>f is undefined.
• Local labels are useful in the bodies of macro definitions so that you
• do not need macro expansion counters to generate unique labels.