[Oberon] ProjectOberon.pdf
Claudio Nieder
private at claudio.ch
Thu Aug 8 13:05:20 CEST 2013
Hi,
> "1. External references are directly patched in the code. The object file contains a list of the locations of
> all external references. It is called the fixup list.
> 2. A separate link table is provided with external references to be converted. The actual references
> within the program code directly refer to these table entries, and only indirectly to the objects."
>
> I don't understand this. If each external reference is patched, why is the
> fixup list needed? Appears that the fixup list is equivalent to the link
> table and the two cases are almost one.
Not at all.
Let's say in your code of Module A you need to call a procedure from another module B.
CALL addressOfPinB
Problem is, at compile time you do not know this addressOfPinB.
In the link table approach (2) you would have a list of all external procedures, and in your code you would fetch the address from the link table and use an indirect call
MOV linkTableEntryForBdotP,Register
CALL (Register)
so on linking only one entry in the link table would need to be fixed to point to B.P.
On the other hand with the fixup list approach (1), you make direct calls, e.g. in the case of calling B.P twice in the Object file you would actually see this:
CALL 00000000
... more code ...
CALL 00000000
Then once the linker has the proper address of B.P it will consult the fixup table which contain the address of all CALL statements and their targets to see where it needs to patch the code and convert in memory the above into
CALL addressOfPinB
... more code ...
CALL addressOfPinB
So these are two fundamentally different approaches to performing the linking. For one the linking table is a structure which needs to be kept in RAM after loading and linking was performed while the fixup information can be discarded after the linking is done. Size wise e.g. if module A calls only one procedure of module B in ten different places then a linking table would need one entry only all 10 calls refer to the same entry, but a fixup table would require 10 entries because 10 CALL statements need to be fixed.
BTW regarding my CALL 0000000 example. For fixup you need to know which CALL statements need to be fixed and with what procedure entry (e.g. B.P) it needs to be fixed. The latter information might be stored in the object file by abusing of the at that time not used address information and some Oberon (or was it Modula-2) compiler as far as I know would do that by writing CALL 00010007 to signify that the seventh procedure of the first referenced module is called. Thus the fixup table would only contain the address of the call statement while the target is encoded in the CALL statement itself.
One more comment regarding the linking table approach(2). In Modula-2 compilers which used that approach you often had a two step indirection. A first table which represents the modules and a second table associated with each module that contains the address of the procedure. So calling a method would look like
MOV modNo(BaseReg),Register ; BaseReg points to module table. Load procedure table for desired module into Register
MOV procNo(Register),Register ; Fetch address of procedure into Register
CALL (Register)
claudio
--
Claudio Nieder, Talweg 6, CH-8610 Uster, Tel +4179 357 6743, www.claudio.ch
More information about the Oberon
mailing list