Recent

Author Topic: linux x64 assembler  (Read 2211 times)

Key-Real

  • Full Member
  • ***
  • Posts: 185
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.

Key-Real

  • Full Member
  • ***
  • Posts: 185
Re: linux x64 assembler
« Reply #1 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.

Kays

  • Hero Member
  • *****
  • Posts: 569
  • Whasup!?
    • KaiBurghardt.de
Re: linux x64 assembler
« Reply #2 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

  • Full Member
  • ***
  • Posts: 102
Re: linux x64 assembler
« Reply #3 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.

Key-Real

  • Full Member
  • ***
  • Posts: 185
Re: linux x64 assembler
« Reply #4 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

  • Full Member
  • ***
  • Posts: 102
Re: linux x64 assembler
« Reply #5 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

  • Full Member
  • ***
  • Posts: 102
Re: linux x64 assembler
« Reply #6 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

  • Full Member
  • ***
  • Posts: 185
Re: linux x64 assembler
« Reply #7 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

  • Full Member
  • ***
  • Posts: 102
Re: linux x64 assembler
« Reply #8 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