Einzelnen Beitrag anzeigen

Amateurprofi

Registriert seit: 17. Nov 2005
Ort: Hamburg
1.077 Beiträge
 
Delphi XE2 Professional
 
#26

AW: In Asm-Prozedur eine Exception auslösen

  Alt 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....
  Mit Zitat antworten Zitat