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
...
But the Delphi code is simple:
str := 'test';
Label1.Caption := str;
But I wanna use this asm ... end;
tag for this.
as following code. But I can't compile this code.
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;
There are several problems with your code, and the biggest one is that TControl.SetText
is private. Your code won't assemble, no matter what you try. You will have to use plain Pascal.
But I'll address the other problems anyway, FYI.
TL;DR
Let's start at the beginning:
lea eax,[ebp-$04]
That tries to take the address of a local variable. You don't know where on the stack this will actually be, so rather use the name. This means you must declare local variables and constants like:
const
C: string = 'test'; // In D7, string is AnsiString
var
X: string;
asm
lea eax,X
mov edx,C
The assembler will add code to set up the stack frame requried for that.
But this way, you are discarding eax, which contains the self pointer. You will have to save this first, either in a local variable or by pushing it on the stack:
var
LSelf: Pointer;
asm
mov LSelf,eax
Later on, you can then use it, e.g. to access the form.
Then you try to access a hidden System function, _LStrAsg
. This is not meant to be used by user code. The compiler has special knowledge about such functions in System.pas. Perhaps it is accessible as
call System.@LStrAsg
But don't bet on it.
Then you try to access TForm1.Label1
. That is not possible like that in assembler either. You could try something like (untested):
mov eax,LSelf
mov eax,[eax].TForm1.Label1
but I am not sure if that works in D7.
So now we have:
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;
But that doesn't compile. The biggest problem is that TControl.SetText
is private. You won't be able to access it. I tried several tricks, but to no avail. All of them result in Undeclared identifier: 'SetText'
.
So what is left is to do it without assembler:
procedure TForm1.Button1Click(Sender: TObject);
begin
Label1.Caption := 'test';
end;