我想在X64 asm块中引发异常。
让我们假设我有这样的功能:
function Example(Values: array of integer): integer;
asm
or rcx,rcx
jz @error
....
我知道我可以只读取指针并获得AV,但是我想提出一个更具描述性的错误。
我可以创建一个额外的功能并调用它:
asm
or rcx,rcx
jz @error
....
@error:
mov ecx, 1
mov rdx, ErrorString
jmp RaiseError
....
function RaiseError(code: integer; const Msg: string);
begin
case code of
1: raise EEmptyArrayError.Create(Msg);
然而,错误将在引起的函数之外发生。如何从(似乎)来自Example
函数内部获取异常。
请注意,这是X64,因此适用于X86的所有SEH答案都不合适,因为X64使用VEH。
答案 0 :(得分:4)
raise的完整语法是:
raise Exception at address
您需要做的就是将当前IP作为参数传递,错误proc可以将其传递给异常。
您可以使用lea rax, [rip]
获取RIP。
因此代码变为:
asm
or rcx,rcx
jz @error
....
@error:
mov ecx, 1
mov rdx, ErrorString
lea r8,[rip]
jmp RaiseError
....
function RaiseError(code: integer; const Msg: string; address: pointer);
begin
case code of
1: raise EEmptyArrayError.Create(Msg) at address;
当然在这种情况下使用起来更容易
function RaiseError(code: integer; const Msg: string);
begin
case code of
1: raise EEmptyArrayError.Create(Msg) at ReturnAddress;
注意强>
在这种情况下,如果你保留jmp,错误似乎来自调用例程,在这种情况下实际上是正确的。如果您希望异常将有罪的手指指向您的asm代码,请使用呼叫。