Previously when I tested accessing the data fields in a simple static fpc object with a x86-32bit target, I could access "self" using the [eax] pointer.
Now I'm trying to move my code to an x86-64bit target and it doesn't appear to work the same way (something different in the calling conventions?).
A simplified example of the code that works ok on the x86 target would be something like this:
program testasm;
{$mode objfpc}{$H+}
{$ASMMODE intel}
uses Classes, sysutils;
Type Ttest = object
lowD : dword;
highD : dword;
procedure getLow(var a : dword); assembler; register;
end;
procedure Ttest.getLow(var a : dword); assembler; register;
asm
push ecx;
mov ecx,[eax]; // get self.lowD
mov [edx],ecx; // store result in var param "a"
pop ecx;
end;
Obviously this is a trivial example just to make sure that I can access parameters as expected, but when I do the equivalent with a Win64 and x86-64 target it compiles ok, but either crashes with a runtime error or returns garbage.
Here is a trivial example of the 64 bit code that doesn't work.
program testasm64;
{$mode objfpc}{$H+}
{$ASMMODE intel}
uses Classes, sysutils;
Type Ttest = object
lowQ : qword;
highQ : qword;
procedure getLow(var a : qword); assembler; register;
end;
procedure Ttest.getLow(var a : qword); assembler; register;
asm
push rcx;
mov rcx,[eax]; // get self.lowQ
mov [rdx],rcx; // store result in var param "a"
pop rcx;
end;
This one compiles ok (fpc 3.04 cross compiler with x86-64 target CPU and Win64 target OS) but the if the method getLow is called it either runtime crashes at the asm line "mov rcx,[rax]" or returns a garbage result (at the same asm line).
So just wondering if the register calling convention different with the x86-64 compiler compared to the regular x86?
BTW. I am running the code on an Intel Core i5, under Windows 7 64 bit OS.