On 08/04/2010 03:57 AM, Hans-Peter Diettrich wrote:

Getting the linear address of a threadvar depends on the OS/FPC implementation.
Of course the compilker needs to adhere to what the OS provides.

As already said multiple times, Win32 for each thread provides a block of user space memory that is addressed by FS and here the base address (to be used via DS) of the threadvar area thus the threadvr itself is rto be accessed using DS. OTOH, Linux X86 provides the address of the threadvar area directly in GS, so that the threadvar needs to be accessed using GS.

As Pascal (other than C) does not provide a means to define that a pointer type is a pointer to a threadvar rather than to a normal var, Pascal alway uses DS to access any variable.

As the user program only sees linear addresses (which have 32 Bit offsets are different regarding to which segment register (or segment register content is used) there are no means for the user land program to calculate a DS-denoted offset (to be used by a pointer) from the GS-denoted offset it knows for the threadvar.

IMO FPC *should* allow to get the address of a threadvar by AddressOf(threadvar)
Usually It does - using DS (the default, thus not explicitly noting a segment register in the ASM instruction). Only with X86/32-Linux when not using a pointer it can't do this (in a high-performance way), as the DS-based offset of the threadvar is not known. In fact it does it "the slow way", doing a function call for any access to a threadvar. As Lazarus does not provide a means to do single setpping in ASM code, I was not able to find out what actually is done here.
- test yourself. It may be possible to get that address also with an LEA instruction (untested).
I did the test.

  lea eax, FS:[$34] resulst in EAX = $34, even though FS is $3B and

  mov eax, FS:[$34] results in correctly loading ax from memory and

  mov eax,[eax] with eax = $34 correctly results in an access violation

in fact I did not suppose that
  lea eax, FS:[$34] would compile at all but it does

the code of lea eax, FS:[$34] is 64 8D 05 34 00 00 00, using the DS prefix "64" while
  the code of lea eax, $34]        is     8D 05 34 00 00 00

I don't see what lea eax, FS:[$34] in fact is supposed to do.
AFAIR Delphi obtains the address of the threadvar memory block via FS/GS,
Right via FS it gets the "thread management block" that contains the (DS-based) offset of the threadvar block, (as stated before. and exactly as M$ C does).
so that it's possible to use the same instruction sequence,
This is what I tried to express in the beginning.
except that finally not the value of the threadvar is retrieved,
Yep, this is as Win32 handles it (but other than Linux does )
but its address (LEA instead of MOV).
Nope.

to read a normal var it needs to do
  mov eax, normvar; (this is implicitely DS based)

to get the pointer to a normal var it needs to do
 lea eax, normalvar; (this is implicitely DS based)

 to read a threadvar, it needs to do
mov eax, FS:(threadmanagementblock+thrfeafvarblockoffset); (this results in the DS-based address of the threadvar block)
 mov eax, [eax+threadvar]

to get the pointer to a thrfeadvar it can do
mov eax, FS:(threadmanagementblock+thrfeafvarblockoffset); (this results in the DS-based address of the threadvar block) lea eax, [eax+threadvar]; (this results in the DS-based address of the threadvar)
or
mov eax, FS:(threadmanagementblock+thrfeafvarblockoffset); (this results in the DS-based address of the threadvar block) add eax, offset (threadvar)]; (this results in the DS-based address of the threadvar)

this can't be done in a single ASM instruction

-Michael
_______________________________________________
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel

Reply via email to