Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi 使用ASM调用对象方法_Delphi_Assembly_Delphi 2010_Basm - Fatal编程技术网

Delphi 使用ASM调用对象方法

Delphi 使用ASM调用对象方法,delphi,assembly,delphi-2010,basm,Delphi,Assembly,Delphi 2010,Basm,为了更好地解释我想要实现的目标,我将从一些有效的东西开始 假设我们有一个过程可以调用另一个过程并向其传递字符串参数: procedure CallSaySomething(AProc: Pointer; const AValue: string); var LAddr: Integer; begin LAddr := Integer(PChar(AValue)); asm MOV EAX, LAddr CALL AProc; end; end; 这是我们将调用的

为了更好地解释我想要实现的目标,我将从一些有效的东西开始

假设我们有一个过程可以调用另一个过程并向其传递字符串参数:

procedure CallSaySomething(AProc: Pointer; const AValue: string);
var
  LAddr: Integer;
begin
  LAddr := Integer(PChar(AValue));
  asm
    MOV EAX, LAddr
    CALL AProc;
  end;
end;
这是我们将调用的过程:

procedure SaySomething(const AValue: string);
begin
  ShowMessage( AValue );
end;
现在我可以打电话给说类似的话了(经过测试,效果良好(:):

我的问题是,我如何实现类似的功能,但这次说点什么应该是一种方法

type
  TMyObj = class
  public
    procedure SaySomething(const AValue: string); // calls show message by passing AValue
  end;
所以,如果你还和我在一起,我的目标是得到一个类似于:

procedure CallMyObj(AObjInstance, AObjMethod: Pointer; const AValue: string);
begin
  asm
    // here is where I need help...
  end;
end;

我已经试过很多次了,但我的装配知识有限。

使用asm的原因是什么

调用objects方法时,实例指针必须是方法调用中的第一个参数

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.

您可能可以通过阅读本文找到解决方法。但何必麻烦呢,声明一个对象的
类型TMyMethod=procedure(Const aValue:string)
并替换
CallMyObj
中的指针类型,并删除
AObjectInstance
。然后您的调用将像
aobjectmethod(aValue)一样简单:
@LURD这是一种非常简单的方式来描述我试图实现的目标,最后,我将使用未知数量的参数和类型的参数调用方法,我找到了一种解决方法…使用“TExec=procedure of Object;”hack和“PUSH DWORD PTR AValue;”,谢谢你的链接谢谢你的代码,到目前为止我已经找到了一种方法,你的方法也很好,使用ASM的原因是因为我发布的“示例”代码是最低限度的,最后,我将传递未知数量的参数和参数类型方法使用TValue的数组
传递未知类型的未知数量的参数。是的,但我想避免使用RTTI,我想使用RTTI获取信息(在启动时),然后使用ASM调用方法。另外,如果您已经发布了方法测试,那么您可以使用LCode:=t.MethodAddress('Test'));并通过LCode而不是@TTest.test
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.