|
|
1.1 ! root 1: /* ! 2: * Example of DOSSETVEC usage ! 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: * ! 39: * Copyright (C) Microsoft Corp. 1986 ! 40: */ ! 41: ! 42: #include <doscalls.h> ! 43: ! 44: int j = 0; /* zero variable for division */ ! 45: ! 46: main() ! 47: { ! 48: ! 49: unsigned int VecNum; /* Exception number (0,4,5,6,7,16) */ ! 50: void (*PrevAddress)(); /* Storage for old vector address, used to reset ! 51: the vector when finished */ ! 52: void (*Dummy)(); /* Dummy variable used when resetting vector */ ! 53: void handler(); /* Name of routine that will handle exception */ ! 54: int i = 9; /* Variable to be divided by 0 */ ! 55: ! 56: /* Set up handler for Exception 0, 'divide by zero' */ ! 57: VecNum = 0; ! 58: DOSSETVEC(VecNum,handler,&PrevAddress); ! 59: ! 60: /* Test the handler */ ! 61: i = i/j; ! 62: printf("new i = %d\n", i); ! 63: ! 64: /* Reset handler for exception 0 */ ! 65: DOSSETVEC(VecNum,PrevAddress,&Dummy); ! 66: } ! 67: ! 68: /* ! 69: * Handler subroutine for testing DOSSETVEC above. ! 70: * This is the routine that will get control ! 71: * when the exception occurs. ! 72: */ ! 73: void handler() ! 74: { ! 75: j = 3; /* Since j=0 caused this exception, setting j=3 will prevent ! 76: the exception from recurring, when we return */ ! 77: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.