Einzelnen Beitrag anzeigen

Kas Ob.

Registriert seit: 3. Sep 2023
355 Beiträge
 
#8

AW: In Asm-Prozedur eine Exception auslösen

  Alt 3. Nov 2023, 12:08
   mov eax,[$00419bc8] // ??? Fragen:
Was wird da in EAX geladen, und wie kann ich das in eigenen Assembler-Routinen realisieren?
In eax a pointer to a type class to create, and Delphi Assembler is very outdated and can't perform many things, in fact it is stuck in 90s, and till this day Embarcadero call it inline-assembler, while it is inline only for 32bit and not inline for 64.

Anyway, i highly recommend to refrain form generating exception from assembly for the same reason above and the share amount of time you will spend on it to work and it most likely will bite you in the butt.

Here a simple code that will work for 32bit
Code:
program AsmException;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils;

type
  TMyException = class(Exception)
  end;

function GetException(Ex: ExceptClass; const Msg: string): Exception;
begin
  Result := Ex.Create(Msg);
end;

procedure ExceptionPas1;
begin
  raise GetException(Exception, 'Error Message from Exception');
end;

procedure ExceptionPas2;
begin
  raise GetException(TMyException, 'Error Message from MyExeption');
end;

procedure ExceptionAsm32;
const
  pMyExClass: ExceptClass = (TMyException);
  LocalExceptionMsg : string = 'Error from Assembly';
asm
  mov    edx, LocalExceptionMsg
  mov    eax, pMyExClass
  Call   GetException
  Call   system.@RaiseExcept
end;
      {
procedure ExceptionAsm64; // will not work, may be wrong, may be just need lot of hand tweaking
const
  pMyExClass: ExceptClass = (TMyException);
  LocalExceptionMsg : string = 'Error from Assembly';
asm
  push   rbp
  mov    rbp, rsp
  mov    rdx, LocalExceptionMsg
  mov    rcx, pMyExClass
  Call   GetException
  mov    rcx, rax
  Call   system.@RaiseExcept
  mov    rsp, rbp
  pop    rbp
end; }

begin
  try
    ExceptionPas1;
  except
    on E: Exception do Writeln(E.ClassName, ' class : ', E.Message);
  end;
  try
    ExceptionPas2;
  except
    on E: Exception do Writeln(E.ClassName, ' class : ', E.Message);
  end;
  try
    ExceptionAsm32;
  except
    on E: Exception do Writeln(E.ClassName, ' class : ', E.Message);
  end;
  Readln;
end.
the result on my PC now
Code:
Exception class : Error Message from Exception
TMyException class : Error Message from MyExeption
TMyException class : Error from Assembly
Yet there is som much to this than what meet the eyes, see, when an exception is raised then unwinding process will issued, for 32bit it is way easier because the system and its API where on the stack, on x64 the calling convention is like Delphi mostly with registers so framed stack will be used and these for optimization reason and unnecessity might be omited, here become problems with guessing where to go next, so you have to be sure for your assembly that framing is OK, in my example for 32 bit it is ok unless your assembly started to grow and the compiler added a frame stack to ruin things, same on x64, which is not working in my above code, i left it as example for who want to try to make it work, it is just waste of time.

My suggestion is that for anything with exception use Pascal/Delphi code, only then the compiler might be helpful, put your exception creation and raising in procedure and call it from assembly, easier and might be safer too.
Kas
  Mit Zitat antworten Zitat