|
|
1.1 root 1: /* 1.1.1.2 ! root 2: * Example of DosSetVec usage 1.1 root 3: * 4: * This call allows a process to register a handler for the 80286 5: * exception vectors. This program works Family API. 6: * 7: * Notes: 8: * 9: * When using the divide by zero trap in Family API mode, be 10: * aware that the 8088/86 leaves the instruction pointer one 11: * beyond the faulting instruction, whereas the 286 and 386 in 12: * real mode leave it pointing to the faulting divide instruction. 13: * The example here assumes a 286 or 386 as it tries to restart 14: * the divide instruction. 15: * 16: * It is possible, as in this example, to have exception handlers 17: * written in C. In general these will be very simple handlers which 18: * print a message before terminating the program. If you wish to 19: * access the full register set at the time the exception occurred, 20: * or get at the address of the failing instruction, then an assembler 21: * handler is needed. Important caveats for handlers in C: 22: * 23: * - disable stack checking in your program (-Gs), since the 24: * handler is entered with unknown segment registers set up. 25: * 26: * - if a program with multiple data segments traps and the 27: * handler uses the segment registers (which are not saved 28: * in C), then on return the program will crash. C handlers 29: * which return to the faulting instruction only work in 30: * simple cases. 31: * 32: * The example here is carefully constructed to successfully return 33: * to the faulting instruction from a C handler. It relies somewhat 34: * on the compiler code generation, and the exact compiler options 35: * used. 36: * 37: * Compile as: cl -AL -G2 -Gs -Lp setvec.c 38: * 1.1.1.2 ! root 39: * Created by Microsoft Corp. 1986 1.1 root 40: */ 41: 1.1.1.2 ! root 42: #define INCL_DOSMISC ! 43: ! 44: #include <os2def.h> ! 45: #include <bsedos.h> 1.1 root 46: 47: int j = 0; /* zero variable for division */ 48: 49: main() 50: { 51: 1.1.1.2 ! root 52: USHORT VecNum; /* Exception number (0,4,5,6,7,16) */ ! 53: PFN PrevAddress; /* Storage for old vector address, used to ! 54: ! 55: reset the vector when finished */ ! 56: PFN Dummy; /* Dummy variable used when resetting vector */ ! 57: int APIENTRY handler(); /* Name of routine that will handle exception */ 1.1 root 58: int i = 9; /* Variable to be divided by 0 */ 59: 60: /* Set up handler for Exception 0, 'divide by zero' */ 61: VecNum = 0; 1.1.1.2 ! root 62: DosSetVec(VecNum,handler,&PrevAddress); 1.1 root 63: 64: /* Test the handler */ 65: i = i/j; 66: printf("new i = %d\n", i); 67: 68: /* Reset handler for exception 0 */ 1.1.1.2 ! root 69: DosSetVec(VecNum,PrevAddress,&Dummy); 1.1 root 70: } 71: 72: /* 1.1.1.2 ! root 73: * Handler subroutine for testing DosSetVec above. 1.1 root 74: * This is the routine that will get control 75: * when the exception occurs. 76: */ 1.1.1.2 ! root 77: int APIENTRY handler() 1.1 root 78: { 79: j = 3; /* Since j=0 caused this exception, setting j=3 will prevent 80: the exception from recurring, when we return */ 81: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.