[fpc-devel] System/370 port. Episode 5 - Addressing data
pascaldragon at googlemail.com
Fri Feb 10 22:41:50 CET 2012
On 10.02.2012 21:48, steve smithers wrote:
> Right - FreePascal - I'm out on a limb here but... All variables (or constants
> or labels for that matter) have to be defined before use to Pascal (See Note 1
> at bottom). At the time they are defined, an entry will be built in a symbol
> table. Now the symbol table has to point at the storage reserved for the
> variable; There are only a limited number of ways it could do that.
> 1) It could hold the absolute address. That's stupid because it means the
> program has to be loaded at the same place all the time.
> 2) It could hold the address of the variable as a relocatable value whose
> value is resolved, either at link-edit time or at program-load time. That
> doesn't really help us when we come to accessing dynamic storage or using
> shared code. So...
> 3) So it's my guess that it holds the address as a pointer to a block of
> storage allocated on the heap or the stack or wherever else it wants to put it.
> and an offset into that block. (plus other stuff like length and type) Sound
> familiar? This is base / displacement addressing! It's just that the
> displacement isn't limited to 4k and the base isn't in a register.
There are basically two locations where a variable can reside:
* on the stack
* on the heap
If the variable is located on the stack then it is normally addressed
using an addressing relative to the stack pointer or the stack base (ESP
and EBP on x86).
If the variable is located on the heap there can be two possibilities
why it resides there:
* it's a global variable, thus the compiler reserves some space for the
variable in the section of the executable (however that is done in the
specific binary format). When the executable is loaded by the OS it
loads the section with all the variables into memory and the runtime
code can then access them. The memory address the compiler uses depends
on the target system. On Windows all variable (and function) addresses
are relative to the base address (which can be changed using a compiler
parameter). This is basically your (1). Windows supports also
relocatable images, but this works by having the OS change all absolute
addresses to their new values when loading (yes, Windows does that). On
Linux there is the concept of Position Independant Executables (PIE)
where all global variables are accessed relative to the Global Offset
Table which normally always resides in a specific register (AFAIK EBX on
x86). There is a non-PIE mode, too, on Linux, but I don't know currently
whether the executable is really not relocateable then.
* it's a memory area that was reserved using "GetMem" or similar calls
to FPC's heap manager. In that case the compiler does not need to do
anything, because this is a runtime allocated memory. The pointer that
points to the memory is then again either a local, stackbased variable
or a global one.
> Or maybe I'm wrong. But I don't think I am. Now the displacement, sorry offset,
> won't have the same limitations that 370 code has, but I've already demonstrated
> a way to handle this. The only realistic example I can think of that runs
> counter to this, is where values are themselves in registers. Then, it's not a
> storage reference problem.
> Note 1. This isn't strictly true I suppose. You can do something like
> With TObject.Create
> However, the compiler has to create a temporary variable to store this value
> in order to access the object, otherwise it's just memory floating around. At
> least I think it does!
Yes, the compiler creates a temporary here.
More information about the fpc-devel