如何在 asm 块中引发异常?
How do I raise an exception in an asm block?
我想在 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。
raise 的完整语法是:
raise Exception at address
您需要做的就是将当前 IP 作为参数传递,错误过程可以将其传递给异常。
您可以使用 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 代码,请使用调用。
我想在 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。
raise 的完整语法是:
raise Exception at address
您需要做的就是将当前 IP 作为参数传递,错误过程可以将其传递给异常。
您可以使用 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 代码,请使用调用。