Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2012-04

Inline assembly using absolute dword ptr

7 messages · 2 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

OBones

Hello,

I'm trying to compile the following code under FreePascal 2.6.0 :

function MyGetCurrentThreadId: DWORD; assembler;
asm

   {$IFDEF WIN32}
   push    ecx
   mov     ecx,fs:[dword ptr $18]
   mov     eax,dword ptr [ecx + $24]
   pop     ecx
   {$ENDIF WIN32}
   {$IFDEF WIN64}
   push    rcx
   mov     rcx,gs:[abs qword ptr $30]
   xor     rax,rax
   mov     eax,dword ptr [rcx + $48]
   pop     rcx
   {$ENDIF WIN64}

end;

It compiles just fine under Delphi XE2 but Freepascal 2.6.0 cannot compile it either for Win32 or Win64.
For Win32, I use those command line arguments

-vewhq -Rintel -FEi386-win32 -Mdelphi -Twin32

and I get these errors

RuntimeCodeUtils.pas(30,19) Error: (7014) Invalid reference syntax
RuntimeCodeUtils.pas(43,4) Fatal: (10026) There were 1 errors compiling
module, stopping
Fatal: (1018) Compilation aborted

For Win64, I use those command line arguments

-vewhq -Rintel -FEx86_64-win64 -Mdelphi -Twin64

and I get these errors

RuntimeCodeUtils.pas(36,23) Error: (7021) Invalid operand type
RuntimeCodeUtils.pas(36,23) Warning: (7032) Calling an overload function
in assembler
RuntimeCodeUtils.pas(36,23) Error: (7014) Invalid reference syntax
RuntimeCodeUtils.pas(43,4) Fatal: (10026) There were 2 errors compiling
module, stopping
Fatal: (1018) Compilation aborted

The function starts at line 26 so the errors are about "dword ptr" and "abs qword ptr" inside the fs and gs square brackets What is wrong with my syntax? Is there another way to write it and get it to work?

Thanks in advance.

Reply by email

OBones
to OBones
OBones wrote
The function starts at line 26 so the errors are about "dword ptr" and "abs qword ptr" inside the fs and gs square brackets What is wrong with my syntax? Is there another way to write it and get it to work?

Ok, answering myself here, the syntax accepted by FPC is the following:

function MyGetCurrentThreadId: DWORD; assembler;
asm

   {$IFDEF WIN32}
   push    ecx
   mov     ecx,dword ptr fs:[$18]
   mov     eax,dword ptr [ecx + $24]
   pop     ecx
   {$ENDIF WIN32}
   {$IFDEF WIN64}
   push    rcx
   mov     rcx,abs qword ptr gs:[$30]
   xor     rax,rax
   mov     eax,dword ptr [rcx + $48]
   pop     rcx
   {$ENDIF WIN64}

end;

However, this gives a warning on line 36, the one with "abs qword ptr" :

RuntimeCodeUtils.pas(36,19) Warning: (7032) Calling an overload function
in assembler

So it seems it thinks that abs is there for calling the "abs" function while I want to specify absolute memory referencing and not relative referencing.

Any hints?

Reply by email

OBones
to Jonas Maebe
Jonas Maebe wrote 5 lines
{$IFDEF WIN64} push rcx mov rcx,gs:[abs qword ptr $30] And this: mov rcx,qword ptr gs:[$30]

Thanks, but does this guarantee absolute indexing? I'm asking because the abs keyword is required when using the same code under Delphi XE2. If I don't use it, that instruction triggers an access violation.

Reply by email

OBones
to OBones
OBones wrote 11 lines
Jonas Maebe wrote: > {$IFDEF WIN64} > push rcx > mov rcx,gs:[abs qword ptr $30] > And this: > mov rcx,qword ptr gs:[$30] Thanks, but does this guarantee absolute indexing? I'm asking because the abs keyword is required when using the same code under Delphi XE2. If I don't use it, that instruction triggers an access violation.

Well, I managed to get my hands on my test project here, and it does work. So there is a difference with Delphi's assembler where it defaults to relative indexing while FPC defaults to absolute in that context.

Thanks for the help

Reply by email

Jonas Maebe
to OBones
OBones wrote
So there is a difference with Delphi's assembler where it defaults to relative indexing while FPC defaults to absolute in that context.

What exactly do you mean by relative addressing in this context? RIP-relative? In FPC, you indeed have to explicitly mention the RIP register in your reference to get RIP-relative addressing.

Jonas

Reply by email

OBones
to Jonas Maebe
Jonas Maebe wrote 5 lines
On 20 Apr 2012, at 17:50, OBones wrote: > So there is a difference with Delphi's assembler where it defaults to relative indexing while FPC defaults to absolute in that context. What exactly do you mean by relative addressing in this context? RIP-relative? In FPC, you indeed have to explicitly mention the RIP register in your reference to get RIP-relative addressing.

What I mean is that under Delphi XE2 in x64 mode, if I type this:

rcx,qword ptr gs:[$30]

I get this generated code:

65488B0D30000000

but if I type the "abs" keyword, I get this:

65488B0C2530000000

while if I do it in x86 mode, I get this :

mov ecx,dword ptr fs:[$18]

648B0D18000000

so it seems that for Delphi XE2 in x64, the default mode, when no keyword is specified, is to use "relative" indexing which is definitely not what I want.
Freepascal, however, appears to use absolute indexing in all mode in this instance, which is fine by me, but something to keep in mind when porting the code.

Regards

Reply by email