[fpc-devel] System/370 port. Episode 5 - Addressing data

Sven Barth 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
>   begin
>   ....
>   end;
> 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 mailing list