Recent

Author Topic: Accessing an object (self) from x86-64 asm?  (Read 6432 times)

Mr.Madguy

  • Hero Member
  • *****
  • Posts: 844
Re: Accessing an object (self) from x86-64 asm?
« Reply #30 on: January 23, 2020, 01:57:22 pm »
That code compliles ok, but it doesn't run correctly for me (this is my older 32bit Windows computer with fpc 2.6.0). It does not transfer the correct value to the "var A" variable.

I'm not 100% certain, but I think that the line "mov %eax, A" actually just does the same as "mov %eax, %edx". That is, a register to register move instead of register to memory.
If () is analog of [] in AT&T syntax, then I expect "mov %eax,(A)" to work, but it looks like, that AT&T implementation is even less compatible with Delphi, than Intel one.
Is it healthy for project not to have regular stable releases?
Just for fun: Code::Blocks, GCC 13 and DOS - is it possible?

PascalDragon

  • Hero Member
  • *****
  • Posts: 5446
  • Compiler Developer
Re: Accessing an object (self) from x86-64 asm?
« Reply #31 on: January 24, 2020, 09:42:49 am »
The following works, though I couldn't get Self to work either, so maybe that's a shortcoming of the AT&T reader.

Code: Pascal  [Select][+][-]
  1. procedure TTest.GetHi(var A: LongInt); assembler;
  2. asm
  3.   mov TTest.Hi(%eax), %eax
  4.   mov %eax, A
  5. end;

That code compliles ok, but it doesn't run correctly for me (this is my older 32bit Windows computer with fpc 2.6.0). It does not transfer the correct value to the "var A" variable.

I'm not 100% certain, but I think that the line "mov %eax, A" actually just does the same as "mov %eax, %edx". That is, a register to register move instead of register to memory.

Hmm, right... Dang it... Probably the AT&T reader would deserve some extensions as well...

That code compliles ok, but it doesn't run correctly for me (this is my older 32bit Windows computer with fpc 2.6.0). It does not transfer the correct value to the "var A" variable.

I'm not 100% certain, but I think that the line "mov %eax, A" actually just does the same as "mov %eax, %edx". That is, a register to register move instead of register to memory.
If () is analog of [] in AT&T syntax, then I expect "mov %eax,(A)" to work, but it looks like, that AT&T implementation is even less compatible with Delphi, than Intel one.

Of course it's less compatible, because Delphi does not support the AT&T syntax at all. So the implementation of such things is completely up to us and probably wasn't that needed. I'll need to check the readers of the other platforms if they allow for more already and if those could be used for the x86 one as well...

BrunoK

  • Sr. Member
  • ****
  • Posts: 452
  • Retired programmer
Re: Accessing an object (self) from x86-64 asm?
« Reply #32 on: January 24, 2020, 11:06:42 am »
This code seems to work
Code: Pascal  [Select][+][-]
  1. program pgmTestAsm;
  2.  
  3. // https://forum.lazarus.freepascal.org/index.php/topic,48176.0.html
  4. {$mode objfpc}{$H+}
  5. {$ASMMODE  ATT}
  6. uses Classes, SysUtils;
  7. type
  8.   TTest = class
  9.     lowD:  dword;
  10.     highD: dword;
  11.     procedure getLow(var a: dword); assembler; register;
  12.   end;
  13. {$DEFINE ASM_1}
  14. {$IFDEF ASM_0}
  15. procedure TTest.getLow(var a: dword); assembler; nostackframe;
  16. asm
  17.   push    TTest.lowD(%eax) // Save Self.lowD on stack
  18.   pop     %eax             // Pop the value to %eax
  19.   mov     %eax, (%edx)     // Move the value to %edx^
  20. end;
  21. {$ENDIF ASM_0}
  22. {$IFDEF ASM_1}
  23. { I386
  24.   %eax : first call param (Self is the implicit first parameter)
  25.   %edx : second call param, pointer to a since a is passed as var }
  26. procedure TTest.getLow(var a: dword); assembler; nostackframe;
  27. asm
  28.   mov     TTest.lowD(%eax), %eax      // Move Self^.lowD to %eax
  29.   mov     %eax, (%edx)                // Move the value to %edx^ (var a)
  30. end;
  31. {$ENDIF ASM_1}
  32.  
  33. var
  34.   vTest : TTest;
  35. begin
  36.   vTest := TTest.create;
  37.   vTest.lowD := 123456789;
  38.   writeln('vTest.lowD=',vTest.lowD);
  39.   writeln('vTest.highD=',vTest.highD);
  40.   vTest.getLow(vTest.highD);
  41.   writeln('vTest.highD=',vTest.highD);
  42.  
  43.   Write('Press enter > '); ReadLn;
  44.  
  45.   vTest.Free;
  46. end.

its the
mov     %eax, (%edx)  // <- parenthesis to write to var pointed by %edx
that makes the difference.

 

TinyPortal © 2005-2018