|
|
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.