[Oberon] Standalone BootLoader format
Andreas Pirklbauer
andreas_pirklbauer at yahoo.com
Tue May 12 17:02:51 CEST 2020
> If more VARs added, e.g.
> VAR x, y, z, a, b, c: INTEGER;
> a := 0; b := 0; c := 0;
>
> Compiled, and then, there is still only 7 words to branch over???
>
> I have also though that those 7 words are to do with boot area limits
> set by BootLoader at boot time.
>
> See PO2013 Applications, page 74.
>
> Quite confused, can you please explain?
> Many thanks
Perhaps another way to look at this is the following:
1. There are ALWAYS 7 words set aside at the beginning of
the *code* section of a standalone program. The BR 7
instruction is the first instruction in the standalone program
that is executed, and it ALWAYS branches to the instruction
at code[8], no matter what - even if you declare 100 variables.
You can see this in ORG.Open.
2. A standalone program ALWAYS uses variable space beginning
at ABSOLUTE memory address 8, no matter what, no matter
how many variables a standalone programs declares.
You can see this in ORP.Module, which sets dc := 8.
Now there are 2 cases:
3. Case #A: The standalone program is loaded at a memory
address DIFFERENT than 0 (the bootloader is such an example
- it is located in ROM at address -8192). In this case, the
standalone program will STILL use addresses starting at
absolute address 8 for its global variables. This means
that you can in fact declare 100 variables, no problem.
"There is plenty of space at the bottom” as Feynman
would say.
For example, let’s say you load your standalone program
(Counter.rsc, say) to absolute address 1024. In that case
Mem[1024] (which is the same as code[0] -you can view a
standalone program as a program which only has a
code section) contains the "B 7” branch instruction
to Mem[1024+8*4] = Mem[1056], which in turn contains
the first “real” instruction of your standalone program.
Please note that in that case, the 7 words code[1]..code[7]
= Mem[1028]..Mem[1052] are not used AT ALL. They are
completely wasted. No use for it. Nothing. Nada.
4. Case #B: The standalone program is ITSELF loaded at
absolute memory address 0. Again, in that case the
standalone program will use addresses starting at
absolute memory address 8 for its global variables,
just like in case #A.
But here, this address 0 now ALSO happens to be the
address of code[0] (because that’s where you have loaded
the standalone program). So code[0] = Mem[0] contains
the B 7 branch to Mem[0 + 8*4] = Mem[32], which in turn
contains the first “real” instruction of your standalone programs.
Now in that case, you only have space for 6 words that you
can use for global variables, namely Mem[8]..Mem[28],
which is the same as code[2]..code[7].
If the compiler did not reserve these words, then the code
section of your standalone program would TRULY start at
absolute address 0 (and the BR instruction would also not
be necessary), and there would be no room for variables.
I think the confusion comes about because a standalone
program does not have - by definition - a regular module
block consisting of a) data, b) code, c) metadata. It “only”
has the “code" that is loaded to a particular address. The
first entry at THAT address is LITERALLY the BR 7
instruction, and there is no such thing a data section.
It’s a bit unfortunate that this is not spelled our more
explicitly in the book, but this is what this is.
You can see this also in the way the Oberon building
tools are implemented. The instruction
ORX.WriteCode M.rsc M.code ~
quite literally extracts “only” the code section and
places it into M.code. And THAT is what gets
loaded into memory, when the standalone
program is transferred to a particular memory
location.
It is only in the case where that address happens
to be 0 that we need to take precaution so that
we don’t run into a conflict. And the way this has
been done in PO 2013 is to simply “reserve” 6
words of the code section itself for global variables.
More information about the Oberon
mailing list