I would like to do this using the assembly, create an instance of the class, call one of its methods and then free the instance.
I know that I am missing something very important and probably very simple, but I do not know what.
program Project2;
{$APPTYPE CONSOLE}
uses
SysUtils;
type
TSomeClass = class(TObject)
private
FCreateDateTime: string;
public
constructor Create;
procedure SayYeah;
end;
constructor TSomeClass.Create;
begin
FCreateDateTime := DateTimeToStr(Now);
end;
procedure TSomeClass.SayYeah;
begin
Writeln('yeah @ ' + FCreateDateTime);
end;
procedure Doit;
asm
CALL TSomeClass.Create; // <= Access Violation
CALL TSomeClass.SayYeah;
CALL TSomeClass.Free;
end;
begin
try
Doit;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
Readln;
end.
FYI: I want to understand how I can achieve this at a low level, and not in another way of doing it.
UPDATE
Thanks to Andreas Reybrand, I managed to find the culprit:
Update2
Thanks to Arno for finding flaws using EBX rather than PUSH / POP EAX
var
TSomeClass_TypeInfo: Pointer;
procedure Doit;
asm
MOV DL, $01;
MOV EAX, TSomeClass_TypeInfo;
CALL TSomeClass.Create;
PUSH EAX;
CALL TSomeClass.SayYeah; // call method
POP EAX;
MOV DL, $01;
CALL TSomeClass.Free; // pointer to instance(Self) is expected in EAX
end;
begin
TSomeClass_TypeInfo := TSomeClass;
try
Doit;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
Readln;
end.
source
share