Metodo di chiamata dell'oggetto usando ASM
-
13-11-2019 - |
Domanda
Per spiegare meglio cosa sto cercando di realizzare, iniziare con qualcosa che funziona.
Dì che abbiamo una procedura che può chiamare un'altra procedura e passare un parametro stringa ad esso:
procedure CallSaySomething(AProc: Pointer; const AValue: string);
var
LAddr: Integer;
begin
LAddr := Integer(PChar(AValue));
asm
MOV EAX, LAddr
CALL AProc;
end;
end;
.
Questa è la procedura che chiameremo:
procedure SaySomething(const AValue: string);
begin
ShowMessage( AValue );
end;
.
Ora posso chiamare Detomething come così (testato e funziona (:):
.
CallSaySomething(@SaySomething, 'Morning people!');
La mia domanda è, come posso ottenere funzionalità simili, ma questa volta Detomething dovrebbe essere un metodo :
.
type
TMyObj = class
public
procedure SaySomething(const AValue: string); // calls show message by passing AValue
end;
Allora, se sei ancora con me ..., il mio obiettivo è quello di arrivare a una procedura simile a:
.
procedure CallMyObj(AObjInstance, AObjMethod: Pointer; const AValue: string);
begin
asm
// here is where I need help...
end;
end;
Ne ho dato un bel po 'di scatti, ma la mia conoscenza di assemblea è limitata.
Soluzione
Qual è il motivo per usare ASM?
Quando si sta chiamando il metodo degli oggetti, quindi il puntatore dell'istanza deve essere il primo parametro nella chiamata del metodo
program Project1;
{$APPTYPE CONSOLE}
{$R *.res}
uses System.SysUtils;
type
TTest = class
procedure test(x : integer);
end;
procedure TTest.test(x: integer);
begin
writeln(x);
end;
procedure CallObjMethod(data, code : pointer; value : integer);
begin
asm
mov eax, data;
mov edx, value;
call code;
end;
end;
var t : TTest;
begin
t := TTest.Create();
try
CallObjMethod(t, @TTest.test, 2);
except
end;
readln;
end.
.