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.

Regards,
Sven
_______________________________________________
fpc-devel maillist  -  [email protected]
http://lists.freepascal.org/mailman/listinfo/fpc-devel

Reply via email to