This is a set of two MACROses which allows to use SEH in the assembly programs.
Code is fully standalone and produces small overhead in the executable.
The usage ideology is different from C(++), though, because assembly gives controlling possibilities which aren't available in the HLL. For instance, the code doesn't call a user-defined code from the SEHandler, but processing an exception, and passing exception information to the user code via appropriate structures, if specified.
Example of usage of the MACROses:
someproc proc ...
LOCAL cont:CONTEXT
LOCAL excr:EXCEPTION_RECORD
LOCAL bIsExc:DWORD
AxEH_try el1,excr,cont,bIsExc
... the code which requires to be covered ...
AxEH_exc el1:
cmp bIsExc,0
jz @noException
... after-exception handling ...
@noException:
...
AxEH_try macro setting the SEH frame up. First parameter is obligated to be specified by the user - it is the code label, which should be unique in the current code scope. Other parameters are optional. Second parameter is a reference to an EXCEPTION_RECORD structure, which will receive the exception information if the exception will occur. Third parameter is a reference to a CONTEXT structure, which will receive the detailed CPU state information if the exception will occur. In a case of no exceptions the contents of the structures is not touched. Fourth parameter is a reference to a DWORD sized flag, which, if specified, will receive the flag of the execution state: if after the SEH block its contents is 0 - there was no exception, if its contents is 1 - there was an exception.
Optional parameters are not abligated to be specified and could be set to 0, but if the code wants to check if there was an exception - it should use the fourth flag parameter, at least.
AxEH_exc macro leaving the SEH frame, and its parameter is a just the code label, which is used in the AxEH_try macro.
The archive attached contains the MACROses itself (AxEH.inc file) and usage example (AxEH.asm) with the executable.
An example EXE output/test input:
#1 [in al,60h] EAX: FFFFFFFF
#2 [div 0] Exception Code: C0000094, exception address: 0040110B
#3.1 Registers BEFORE calling a proc which will change the regs and fail:
EAX: 00000044, ECX: 77C418BF, EDX: 77C61B78, EBX: 7FFFF000
ESP: 0012FCA0, EBP: 0012FFC0, ESI: 00380035, EDI: 00330032
#3.2 Registers AFTER calling a proc which have changed the regs and failed:
EAX: 00000044, ECX: 77C418BF, EDX: 77C61B78, EBX: 7FFFF000
ESP: 0012FCA0, EBP: 0012FFC0, ESI: 00380035, EDI: 00330032
#3.3 Registers which were IN the called proc at the time it failed:
EAX: 00000012, ECX: 00000034, EDX: 00000056, EBX: 00000078
ESP: 0012F844, EBP: 00000090, ESI: 000000AB, EDI: CDEF0056
#3.4 The exception code: C0000005, address: 0040107C
#4.1 Enter the bare hex address to peek the byte from, -1 to finish: 1
#4.1 Failed to peek the byte value at the specified address!
#4.1 Enter the bare hex address to peek the byte from, -1 to finish: 400000
#4.1 The byte value is: 4D
#4.1 Enter the bare hex address to peek the byte from, -1 to finish: -1
Find and press [Any] key to exit ...