Recent

Author Topic: linux x64 assembler  (Read 1029 times)

Key-Real

  • New Member
  • *
  • Posts: 10
linux x64 assembler
« on: February 27, 2021, 05:11:59 pm »
Im under intel 64x linux:

i have procedure putPixel(where:gfxImage;x,y,col:dword);
gfxImage is:        data:pointer; width,hieght:dword;

If I do
putPixel(where:gfxImage;x,y,col:dword); assembler;
asm
         xor eax,eax
end;

I make a breakpoint to xor eax,eax.

the Lazarus debuger Local Variables shows me where.width = unrecodnizible value, so as where.height
if i change width and hieght to qword it works but I cannot change this type because of my architekture

If I do
putPixel(where:gfxImage;x,y,col:dword);
begin
asm
         xor eax,eax
end;
end;
everything works.

I need a pure assembler procedure.

jamie

  • Hero Member
  • *****
  • Posts: 4376
Re: linux x64 assembler
« Reply #1 on: February 27, 2021, 06:18:10 pm »
not sure how the ABI works in Linux but looking at your code I can assume its a Intel 32 and as such could match the register calling of Delphi..

first parameter in EAX,
second in ECX;
third in EDX;

Any more params are pushed on the stack..

return types for simple things are in EAX,AX and AL;

The assembler should be able at actually resolve the registers..

Procedure Test(First,Second,Third);
Begin
Asm
  Mov #0, First;
….
end;

that should compile to a move to a $EAX ,

But keep in mind the return value if a function needs a EAX register usage..
etc

There is much more but maybe this will get you going..

in 64 bit land the ABI calling is a little different on windows...
The only true wisdom is knowing you know nothing

Key-Real

  • New Member
  • *
  • Posts: 10
Re: linux x64 assembler
« Reply #2 on: February 27, 2021, 06:53:09 pm »
under windows64 I do not have this roblem,
dont fink its 32bt, perhaps the xor eax,eax is choosen porley
make it  xor rax,rax
I need a linux solution

AMD64:
the register parameter passing order on Windows is
rcx - rdx - r8 - r9 - rest on stack
while everyone else uses
rdi - rsi - rdx - rcx - r8 - r9 - rest on stack.

jamie

  • Hero Member
  • *****
  • Posts: 4376
Re: linux x64 assembler
« Reply #3 on: February 27, 2021, 07:15:33 pm »
yeah, we window users are bunch of trouble makers.. :o
The only true wisdom is knowing you know nothing

Kays

  • Sr. Member
  • ****
  • Posts: 299
  • Whasup!?
    • KaiBurghardt.de
Re: linux x64 assembler
« Reply #4 on: February 27, 2021, 08:03:39 pm »
Im under intel 64x linux: […]
the Lazarus debuger Local Variables shows me where.width = unrecodnizible value, so as where.height […]

I can’t confirm your issue. If I understand correctly
Code: Pascal  [Select][+][-]
  1. type
  2.         gfxImage = record
  3.                         data: pointer;
  4.                         width, height: dWord;
  5.                 end;
then the local variables dialog shows:
NameValue
COL1337
WHERE{DATA = 0x0, WIDTH = 10101010, HEIGHT = 32767}
X42
Y1
once inside of putPixel. Are you sure you are using the dWord? The system.dWord? Are operator overloads interfering? What’s the sizeOf of (your) gfxImage and every individual member?

PS: It’s probably best to use one of the nop words, like xchg eax, eax, as a dummy instruction.
« Last Edit: February 27, 2021, 11:08:41 pm by Kays »
Yours Sincerely
Kai Burghardt

mika

  • New Member
  • *
  • Posts: 29
Re: linux x64 assembler
« Reply #5 on: February 28, 2021, 04:50:43 pm »
Im under intel 64x linux: […]
the Lazarus debuger Local Variables shows me where.width = unrecodnizible value, so as where.height […]

I can’t confirm your issue. If I understand correctly


there are problems.
two solutions for you
1) make record packed as we will relay on field positions
access parameters in linux64 as in code example

Code: Pascal  [Select][+][-]
  1. type
  2.      gfxImage = packed record
  3.           data: pointer;
  4.           width, height: dWord;
  5.      end;
  6.  
  7. function putPixel(where:gfxImage;x,y,col:dword):dword; assembler; nostackframe;
  8. asm
  9.      mov eax,x   // x in edx
  10.      mov eax,y   // y in ecx
  11.      mov eax,col // col in r8d
  12.      mov rax,rdi // where.data in rdi
  13.  
  14.      mov rax,rsi // where.width and where.height in rsi
  15.  
  16.      mov eax,esi // where.width
  17.      mov rax,rsi
  18.      shr rax,32  // where.height in upper part of rsi
  19. end;
  20.  

sorry, but debugger wont be able to see where.width.

2) make your  "width" and  "height"  qWord for 64 bit target.

Code: Pascal  [Select][+][-]
  1. type
  2.      gfxImage = record
  3.           data: pointer;
  4.           width, height: qWord;
  5.      end;
  6.  
  7. function putPixel(where:gfxImage;x,y,col:dword):dword; assembler; {nostackframe;}
  8. asm
  9.      mov eax,x  //edi
  10.      mov eax,y  //esi
  11.      mov eax,col  //edx
  12.  
  13.      mov rax, where.data  // allocated on stack
  14.      mov rax, where.width
  15.      mov rax, where.height
  16.  
  17. end;
  18.  
  19.  

debugger should be able to see where.width and where.height as they are on stack now.

jamie

  • Hero Member
  • *****
  • Posts: 4376
Re: linux x64 assembler
« Reply #6 on: February 28, 2021, 05:33:19 pm »
Just let the compiler do it for you..

PutPixel(Var gfxImage,.....);


or

PutPixel(……):TGfxImage; //which is a  record so this should work.
Begin
 Result.Width := ?
 Result.Height:= ?
  ect…
end;

 You could even inline that, it may save a little on stack calls.

but the PutPixel(Var gfxImage, ……); results in the same thing, a pointer back to the record

But don't follow my advise because the next compiler release may break it, also your ASM code may break too if you manage to get this working due to remapping of register usage..

The only true wisdom is knowing you know nothing

Key-Real

  • New Member
  • *
  • Posts: 10
Re: linux x64 assembler
« Reply #7 on: March 01, 2021, 05:00:45 pm »
Mikas solutions works.

But i die Not understand why gfximage.width ist in rsi.

Logicaly IT should be in [rdi+8]

In rsi should be the next Parameter, hire x


mika

  • New Member
  • *
  • Posts: 29
Re: linux x64 assembler
« Reply #8 on: March 01, 2021, 09:05:23 pm »
But i die Not understand why gfximage.width ist in rsi.

Logicaly IT should be in [rdi+8]

In rsi should be the next Parameter, hire x

according to ABI:
Quote
Arguments of type __int128 offer the same operations as INTEGERs,
yet they do not fit into one general purpose register but require two registers.
For classification purposes __int128 is treated as if it were implemented
as:
typedef struct {
long low, high;
} __int128;

Is your gfximage record __int128? On first glance it does not look like, but it has 128 bits. Is it compiler bug or it has to be so?

Windows has different ABI can not comment on that part.


mika

  • New Member
  • *
  • Posts: 29
Re: linux x64 assembler
« Reply #9 on: March 01, 2021, 09:11:16 pm »
Logicaly IT should be in [rdi+8]

In rsi should be the next Parameter, hire x

if you want to reference where.width as [rdi+8] you have to define function header like
Code: Pascal  [Select][+][-]
  1. procedure putPixel( var where:gfxImage;x,y,col:dword); assembler;

Key-Real

  • New Member
  • *
  • Posts: 10
Re: linux x64 assembler
« Reply #10 on: March 02, 2021, 04:03:20 pm »
I do not want to make where:gfxImage as var.
The pair rdi and rsi is now clear, but what If i have:
Type
 GfxImage = packed record
                          Where:Pointer;
                           Wirth, height: dword;
                           Value1, value2: dword;
                      End;
How then access value1 and value2.

mika

  • New Member
  • *
  • Posts: 29
Re: linux x64 assembler
« Reply #11 on: March 03, 2021, 12:07:28 pm »
Type
 GfxImage = packed record
                          Where:Pointer;
                           Wirth, height: dword;
                           Value1, value2: dword;
                      End;
How then access value1 and value2.

Sad part is you would have to modify your assembler code.
It all will be on stack. rbp registers is used to access variables on stack. Then you can directly access all member of record by names ( mov eax, where.width ).

 

TinyPortal © 2005-2018