Registriert seit: 17. Nov 2005
Ort: Hamburg
1.077 Beiträge
Delphi XE2 Professional
|
AW: In Asm-Prozedur eine Exception auslösen
6. Nov 2023, 06:45
I am trying here to explain and language barrier is playing huge role.
This will work on x64 for this exact procedure
Code:
PROCEDURE test;
const
pExClass:ExceptClass=( Exception );
sErr:String=' My message ';
asm
{$IfDef CPUX86}
mov ecx,sErr
mov dl ,1
mov eax,pExClass
call Exception .Create
call System.@RaiseExcept
{$Else}
push rbp
sub rsp,$20
mov rbp,rsp
mov r8,sErr
mov dl ,$01
mov rcx,pExClass
call Exception .Create // Seems to work
mov rcx,rax
call System.@RaiseExcept // Here it crashes. " ACCESS VIOLATION"
lea rsp,[rbp+$20]
pop rbp
pop rbp
{$EndIf}
end ;
BUT will fail on many other places and different situations or for just little more complex assembly above that system.@RaiseExcept !!!
The reasoning : i put a frame stack for it and so it worked, now if your assembly is using variables or utilizing the stack or even the compiler went ahead and added a frame on its own to build right assembly, we will end up with double frame and whole different mess and that solution become broken again and you should remove that stack i introduced, this is one hand on other hand this can't be guaranteed to be working on future compiler, tested it on XE8 and your test procedure and it is raising stack overflow on my machine not an access violation!
That why i moved the raising call to its own pascal procedure, this guaranteed to have right frame stack and the compiler will handle it right, as i said that in my humble opinion and according to my experience this is the closest for assembly to raise an exception without braking things every time you modify your assembly and guaranteed to be working on different compilers including future ones, also will not send tools like EurekaLog after witch hunting!
I hope that is clear.
ps : this was a good question and might help many who interested.
Thank you, Kas Ob.
Funny thing.
Just before entering the DP I looked, how
Delphi-Quellcode:
PROCEDURE TestRaise;
const sErr:String=' Meine Meldung';
begin
raise Exception.Create(sErr);
end;
is translated to asm, found the following
Code:
FS_Main.pas.5041: begin
00000000005D3070 55 push rbp
00000000005D3071 4883EC20 sub rsp,$20
00000000005D3075 488BEC mov rbp,rsp
FS_Main.pas.5042: raise Exception.Create(sErr);
00000000005D3078 488B0D4901E5FF mov rcx,[rel $ffe50149]
00000000005D307F B201 mov dl,$01
00000000005D3081 4C8B0500460300 mov r8,[rel $00034600]
00000000005D3088 E81307E6FF call Exception.Create
00000000005D308D 4889C1 mov rcx,rax
00000000005D3090 E8EB73E3FF call @RaiseExcept
FS_Main.pas.5043: end;
00000000005D3095 488D6520 lea rsp,[rbp+$20]
00000000005D3099 5D pop rbp
00000000005D309A C3 ret
copied it into my test-procedure ... and it worked.
Then i wanted to post it and saw that did the same.
Again thank you
Gruß, Klaus
Die Titanic wurde von Profis gebaut,
die Arche Noah von einem Amateur.
... Und dieser Beitrag vom Amateurprofi....
|
|
Zitat
|