Unit1.TForm1.Button1Click
push 0
push ebx
mov ebx, eax
...
lea eax,[ebp-4]
mov edx,44EB18;`test`
call LStrLAsg
mov edx,dword ptr [ebp-4]
mov eax,dword ptr [ebx+2FC];TForm1.Label1:TLabel
call TControl.SetText
...
但是Delphi代码很简单:
str := 'test';
Label1.Caption := str;
但是我想使用这个asm ... end;
标签。
如以下代码。但是我不能编译这段代码。
asm
lea eax,[ebp-4]
mov edx, 'test'
call @LStrLAsg
mov edx,dword ptr [ebp-4]
mov eax, TForm1.Label1; TForm1.Label1:TLabel
call TControl.SetText
end;
答案 0 :(得分:2)
您的代码有几个问题,最大的问题是TControl.SetText
是私有的。无论尝试什么,您的代码都不会汇编。您将不得不使用普通的Pascal。
但我还是会解决其他问题,仅供参考。
TL; DR
让我们从头开始:
lea eax,[ebp-$04]
试图获取局部变量的地址。您不知道它实际在堆栈中的什么位置,因此请使用名称。这意味着您必须声明局部变量和常量,例如:
const
C: string = 'test'; // In D7, string is AnsiString
var
X: string;
asm
lea eax,X
mov edx,C
汇编器将添加代码以设置为此所需的堆栈框架。
但是,这样一来,您将丢弃包含自我指针的eax。您必须先将其保存在本地变量中或通过将其压入堆栈:
var
LSelf: Pointer;
asm
mov LSelf,eax
以后,您可以使用它,例如访问表格。
然后,您尝试访问隐藏的系统功能_LStrAsg
。用户代码不打算使用它。编译器在 System.pas 中具有有关此类功能的特殊知识。也许可以通过
call System.@LStrAsg
但是不要打赌。
然后,您尝试访问TForm1.Label1
。也不可能像在汇编程序中那样。您可以尝试类似(未经测试)的操作:
mov eax,LSelf
mov eax,[eax].TForm1.Label1
但我不确定这是否适用于D7。
现在我们有了:
const
C: string = 'test'; // In D7, this is an AnsiString, hence _LStrAsg
procedure TForm1.Button1Click(Sender: TObject);
var
S: string;
LSelf: Pointer;
asm
mov LSelf,eax // save self pointer
lea eax,S // S := C;
mov edx,C
call System.@LStrAsg
mov eax,LSelf // Self.Label1.Caption := S;
mov eax,[eax].TForm1.Label1
mov edx,S
call TControl.SetText
end;
但这无法编译。最大的问题是TControl.SetText
是私有。您将无法访问它。我尝试了几种技巧,但无济于事。它们全都产生Undeclared identifier: 'SetText'
。
那么剩下的就是不用汇编程序了:
procedure TForm1.Button1Click(Sender: TObject);
begin
Label1.Caption := 'test';
end;