What I would like to do is, using assembly, create a class instance, call one of it's methods and then free the instance.
I know I'm missing something very important and probably very simple, but I don't 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 low level, not another way of doing it.
UPDATE:
Thanks to Andreas Rejbrand, I've managed to find the culprit:
Update2:
Thanks to Arnaud for finding flaw 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.
You can read about this in an excellent guide to Delphi assembly programming, originally found here. Unfortunately, the site is down, but you can find an archived version here. Look in particular at page 5.