Creating an instance of a class using the built-in assembler Delphi

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.
+5
source share
2 answers

Delphi, . , , . , , . 5.

+2

asm .

ebx, . .

:

procedure Doit(ClassType: pointer);
asm // eax=TList
  mov dl,true // hidden boolean 2nd parameter
  call TObject.Create
  push eax
  call TList.Pack
  pop eax
  call TObject.Free
end;

DoIt(TList);

try...finally.:)

mov dl,true . - EMB:

, , , .

False , . . True , . , Self, EAX.

False . , . True , destructor . , .

, . DL . . cdecl, stdcall safecall, Self.

DL , , DL , BeforeDestruction AfterConstruction .

, , eax nil, , :

procedure Doit(ClassType: pointer);
asm // eax=TList
  mov dl,true
  call TObject.Create
  push eax
  call TList.Pack
  pop eax
  mov dl,true
  call TList.Destroy
end;

asm . , . class , , asm; , asm !

+10

All Articles