joerg.straube at iaeth.ch
Thu Dec 17 00:59:11 CET 2020
> From: Andreas Pirklbauer <andreas_pirklbauer at yahoo.com>
> Date: Mon, 18 Nov 2019 21:04:32 +0100
>> the compiler generates the instruction
>> | BL (4) | cond (4) | mno (4) | pno (8) | pc-fixorgP (12) |,
Your question deep dives directly into the very tricky (and nasty) implementation details of the compiler.
And unfortunately to say, „the RISC architecture“ will not help at all to understand what the compiler generates here.
Normally, you may assume that the compiler generates assembler instructions that comply to the RISC5 architecture. But there are exceptions to this rule, where the compiler does something completely different. And the mentioned example above is unfortunately one if those few exceptions.
What is the problem the compiler has to solve? It‘s about „seperate compilation“ and „dynamic module loading“.
You know, that in Oberon you can write
BEGIN A.P; END B.
At compile time of B, the compiler does not know at what memory address the code of module A is loaded by the loader. That means the compiler can not use ABSOLUTE memory addresses in branch/jump instructions to A.P. The compiler needs to generate somehow code with RELATIVE offsets to the start of P.
To complicate things, Oberon allows to change the implementation of procedure P in module A without the need to recompile B. That makes the code generation for A.P in module B even worse as even the relative offset of the start of P may change from compilation of A to the next compilation of A.
In short, the compiler can not solve this without help. The only instance that knows where in memory the module A and B are located is the loader (Modules.Load) and the loader also keeps a list of start offsets to all exported procedures.
In this case, the compiler does NOT generate a valid RISC5 assembler instruction, but instead a command for the loader what he has to do. After loading the code into memory, the loader modifies all jump instructions to imported procedures. To do so, the loader needs a module number for A and a procedure number of P. It looks up in his internal tables where currently A is located and where procedure P currently starts, calculates the correct address and generates a valid RISC5 jump instruction.
I hope my explanation helped a little and does not confuse..
does not help here
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the Oberon