; Listing7-5.asm ; ; A program that demonstrates handling ; an exception using the try/endtry ; macros. option casemap:none .nolist include aoalib.inc include aoaExcepts.inc includelib aoalib.lib .list .const ; Program title: align word ttlStr byte "Listing 7-5", 0 .code ; tstSEH- ; ; This procedure tests exception handling code in ; assembly language. tstSEH xproc (filterProc(tstSEH), <>) local endTryPtr:qword local shadowStorage[48]:byte try call print byte "startTry: int 3 is next instr" byte nl, 0 int 3 ;Cause an exception call print byte "This should not print" byte nl, 0 exception(ex(brkpt)) ; Here's the code that executes whenever ; a breakpoint occurs in the protected ; block. ; ; Upon entry into this code, RAX contains ; a pointer to the DispatcherContext ; record. Print a couple of useful ; values from that record: mov edx, [rax].ExceptionRecord_t.ExceptionCode call print byte "Breakpoint encountered (0x%x)" byte nl, 0 finally ; Here's the finally code: call print byte "Executed finally code", nl, 0 ; This is where the code exits the ; protected loop. endtry ; Generate the epilog code (including ret) and end ; the procedure: tstSEH endxp() ;-------------------------------------------------- ; ; Here is the main assembly language function. public asmMain ; For the main assembly procedure, preserve all the ; non-volatile registers. It would be cool to save ; the XMM non-volatile registers, too, but there isn't ; room in the prolog for them. ; ; Had this code used a biased frame pointer (RBP) value, ; it could have gotten away with saving them. Epilog ; and prolog macros don't allow that, however. So this ; code preserves what it can (the general-purpose 64-bit ; non-volatile registers). asmMain xproc (frame,) local shadowStorage[56]:byte ; Call the procedure the demonstrates exception handling: call print byte "Calling tstSEH", nl, 0 ; Call the procedure that raises an exception: call tstSEH call print byte "Back from tstSEH", nl, 0 asmMain endxp() end