You are not logged in.
Pages: 1
Dear Mr. Bouchez
I like to know where the parameters of object-function(s)/procedure(s) [e.g. procedure (...) of object like TNotifyEvent] are posted when they are called through the event handler.I am practicing low level coding and I am very new to it, as a practice, I have written an assembley event handler routine for OnKeyPress Event for a decendant of TCustomEdit class, and when I want to access the by-reference parameter called Key via [EDX] or by its name, I encountered an error, an Exception of class EAccessViolation. but when I use a temporary character variable, and assign the Key parameter to it, it works !!!
now I like to know how I can access that parameter (Key) directly, without using a temorary variable.
Here's the routine: Here I assumed that the address of Key param has been passed to EDX (like native procedures), but this code does not work, but it works correctly, if it is written as a native procedure.
I have checked that the EDX does not contain the address of Key parameter, so I changed this code by replacing the EDX register with the name of the parameter, but It failed again, and I like to know where the Key param is located ??
// DOES NOT WORK :(( procedure Tfrmmenumng.edGroupNameKeyPress(Sender: TObject; var Key: Char); asm mov ecx, dword ptr [edx] cmp cx, '9' ja @@KillChar cmp cx, '0' jb @@CheckForBackSpace ret CheckForBackSpace: cmp cx, 8h // VK_BACK je @@Quit @@KillChar: xor ecx, ecx mov dword ptr [edx], ecx push ecx call MessageBeep @@Quit: end; //====================================== // DOES NOT WORK :(( procedure Tfrmmenumng.edGroupNameKeyPress(Sender: TObject; var Key: Char); asm mov ecx, dword ptr [Key] cmp cx, '9' ja @@KillChar cmp cx, '0' jb @@CheckForBackSpace ret CheckForBackSpace: cmp cx, 8h // VK_BACK je @@Quit @@KillChar: xor ecx, ecx mov dword ptr [Key], ecx push ecx call MessageBeep @@Quit: end; //====================================== // BUT THIS UGLY WORKS ???? procedure Tfrmmenumng.edGroupNameKeyPress(Sender: TObject; var Key: Char); var cTemp: Char; label CheckForBackSpace, KillChar, Quit; begin cTemp := Key; asm movzx ecx, cTemp cmp cx, '9' ja KillChar cmp cx, '0' jb CheckForBackSpace end; Exit; CheckForBackSpace: asm cmp cx, 8h // VK_BACK je Quit end; KillChar: asm xor ecx, ecx mov cTemp, cx push ecx call MessageBeep end; Key := cTemp; Quit: end;
Thanks in advance.
best regards,
Offline
In a method, you have the "self" parameter that is always transmitted in asm as first parameter.
So for:
procedure Tfrmmenumng.edGroupNameKeyPress(Sender: TObject; var Key: Char);
you have:
eax = self
edx = Sender
ecx = @key
So you'll have to change your asm code to use these registers instead of eax=Sender and edx=@key.
Happy coding!
Offline
Here could be the resulting code (compatible with Delphi 7 up to Delphi 2010):
procedure Tfrmmenumng.edGroupNameKeyPress(Sender: TObject; var Key: Char);
asm
{$ifdef UNICODE}
movzx eax, word ptr [ecx]
{$else}
movzx eax, byte ptr [ecx]
{$endif}
cmp eax, '9'
ja @@KillChar
cmp eax, '0'
jb @@CheckForBackSpace
ret
CheckForBackSpace:
cmp eax, 8h // VK_BACK
je @@Quit
@@KillChar:
xor eax, eax
mov dword ptr [ecx], eax
push eax
call MessageBeep
@@Quit:
end;
But I guess the Delphi compiler is able to code it in a similar manner.
No speed we'll be noticed here, even more because it's an even handler, which rely on both WinApi + VCL, therefore is somewhat CPU consuming!
But that's a nice try to write assembler.
Offline
Pages: 1