Recent

Author Topic: asmgetmem  (Read 5892 times)

tormods

  • New Member
  • *
  • Posts: 17
asmgetmem
« on: June 05, 2014, 10:39:07 pm »

To call getMem from assembly there has been made a separate function: asmgetmem since assembler can not decide on overloaded functions. Trying to call this function ends up with unknown function. What has happen with this? Tried to call also getmem from assembler, but as expected this ended with an exception.

call system.@asmgetmem

tormods

Leledumbo

  • Hero Member
  • *****
  • Posts: 8273
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: asmgetmem
« Reply #1 on: June 06, 2014, 02:34:19 am »
What FPC version are you using? AsmGetMem/AsmFreeMem doesn't exist in recent release.

tormods

  • New Member
  • *
  • Posts: 17
Re: asmgetmem
« Reply #2 on: June 06, 2014, 08:13:00 am »
I am using fpc 2.6.4. I suspected that these functions had disapeared, any workaround?

tormods

Leledumbo

  • Hero Member
  • *****
  • Posts: 8273
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: asmgetmem
« Reply #3 on: June 06, 2014, 08:31:29 am »
You can export a symbol accessible from asm using public name modifier, wrapping one of the overloaded GetMem, probably with a simpler calling convention specifier for easier access (unless you understand the register calling convention).

tormods

  • New Member
  • *
  • Posts: 17
Re: asmgetmem
« Reply #4 on: June 09, 2014, 04:54:23 pm »
I'm not sure how to use 'public name', how could it be implemented in this case?

I made a short pascal program to test the assembler result and to check result of the two overloded routines GetMem. I also for the fun retrieved the address of GetMem. As can be seen there are two different addresses for the two routines. When address is retrieved the address to the first routine is given, but when calling from assembly I like to use the other which has a pointer to allocated memory. Can anyone give me a sample, I guess this issue will be valid for calling other overloaded functions in fpc.


Code: [Select]
[code]TFORM1__BUTTON1CLICK
00425DF2 e583                     in     eax,0x83
00425DF4 ec                       in     al,dx
00425DF5 108945f88955             adc    BYTE PTR [ecx+0x5589f845],cl
00425DFB fc                       cld   
00425DFC b880d64000               mov    eax,0x40d680
00425E01 8945f4                   mov    DWORD PTR [ebp-0xc],eax
00425E04 b8e8030000               mov    eax,0x3e8
00425E09 e8c278feff              call   0x40d6d0 <SYSTEM_GETMEM$LONGWORD$$POINTER>
00425E0E 8945f4                   mov    DWORD PTR [ebp-0xc],eax
00425E11 8d45f0                   lea    eax,[ebp-0x10]
00425E14 bae8030000               mov    edx,0x3e8
00425E19 e86278feff               call   0x40d680 <SYSTEM_GETMEM$POINTER$LONGWORD>
00425E1E b8f4010000               mov    eax,0x1f4
00425E23 e8a878feff               call   0x40d6d0 <SYSTEM_GETMEM$LONGWORD$$POINTER>
00425E28 8945f4                   mov    DWORD PTR [ebp-0xc],eax
00425E2B c9                       leave 
00425E2C c3                       ret   

procedure TForm1.Button1Click(Sender: TObject);

var p,pt:pointer;

begin
  p:= @(getmem);  // returning x40d680
  p:= getmem(1000);  // calling x40d6d0
  GetMem(pt,1000);  // calling x40d680
  p:=getmem(500); // calling 0x40d6d0
end;                 

engkin

  • Hero Member
  • *****
  • Posts: 2513
Re: asmgetmem
« Reply #5 on: June 09, 2014, 05:40:59 pm »
I'm not sure how to use 'public name', how could it be implemented in this case?
I think something like this:
Code: [Select]
function AsmGetMem(vSize: PtrUInt):pointer;register;[public];
begin
  Result := GetMem(vSize);
end;
When you call it using assembly you pass the size in EAX and when it returns you receive the result in EAX as well. I did not try it, but you can see the generated assembly code if you add -al in your project "Other - Custom options"

Leledumbo

  • Hero Member
  • *****
  • Posts: 8273
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: asmgetmem
« Reply #6 on: June 09, 2014, 06:25:17 pm »
I'm not sure how to use 'public name', how could it be implemented in this case?
I think something like this:
Code: [Select]
function AsmGetMem(vSize: PtrUInt):pointer;register;[public];
begin
  Result := GetMem(vSize);
end;
When you call it using assembly you pass the size in EAX and when it returns you receive the result in EAX as well. I did not try it, but you can see the generated assembly code if you add -al in your project "Other - Custom options"
Code: [Select]
public name 'AsmGetMem';would be better, since the label at assembly level will be exactly as written. Remember that by default FPC mangles name, so it will be quite difficult to call Pascal routine from assembly.

engkin

  • Hero Member
  • *****
  • Posts: 2513
Re: asmgetmem
« Reply #7 on: June 09, 2014, 11:48:33 pm »
Code: [Select]
public name 'AsmGetMem';would be better, since the label at assembly level will be exactly as written. Remember that by default FPC mangles name, so it will be quite difficult to call Pascal routine from assembly.
It seems to me that FPC name mangling would be a problem if you were to use {$ASMMODE direct} only. Other than that I was able to call AsmGetMem as is without adding name 'AsmGetMem' to public and FPC took care of name mangling. So the above code worked with:
Code: [Select]
{$ASMMODE intel}

procedure Test;assembler;
asm
  mov eax, $1234
  call AsmGetMem
end;

Leledumbo

  • Hero Member
  • *****
  • Posts: 8273
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: asmgetmem
« Reply #8 on: June 10, 2014, 02:00:49 am »
It seems to me that FPC name mangling would be a problem if you were to use {$ASMMODE direct} only. Other than that I was able to call AsmGetMem as is without adding name 'AsmGetMem' to public and FPC took care of name mangling. So the above code worked with:
Code: [Select]
{$ASMMODE intel}

procedure Test;assembler;
asm
  mov eax, $1234
  call AsmGetMem
end;
I mean real (external) assembly, not inline assembly. I have no idea what assembly the OP means.

engkin

  • Hero Member
  • *****
  • Posts: 2513
Re: asmgetmem
« Reply #9 on: June 10, 2014, 02:06:16 am »
You have a point, I assumed inline assembler where public does not make sense. It is up to the OP to clarify it.

 

TinyPortal © 2005-2018