|
|
Microsoft OS/2 SDK 03-01-1988
/*
* Example of DosSetVec usage
*
* This call allows a process to register a handler for the 80286
* exception vectors. This program works Family API.
*
* Notes:
*
* When using the divide by zero trap in Family API mode, be
* aware that the 8088/86 leaves the instruction pointer one
* beyond the faulting instruction, whereas the 286 and 386 in
* real mode leave it pointing to the faulting divide instruction.
* The example here assumes a 286 or 386 as it tries to restart
* the divide instruction.
*
* It is possible, as in this example, to have exception handlers
* written in C. In general these will be very simple handlers which
* print a message before terminating the program. If you wish to
* access the full register set at the time the exception occurred,
* or get at the address of the failing instruction, then an assembler
* handler is needed. Important caveats for handlers in C:
*
* - disable stack checking in your program (-Gs), since the
* handler is entered with unknown segment registers set up.
*
* - if a program with multiple data segments traps and the
* handler uses the segment registers (which are not saved
* in C), then on return the program will crash. C handlers
* which return to the faulting instruction only work in
* simple cases.
*
* The example here is carefully constructed to successfully return
* to the faulting instruction from a C handler. It relies somewhat
* on the compiler code generation, and the exact compiler options
* used.
*
* Compile as: cl -AL -G2 -Gs -Lp setvec.c
*
* Created by Microsoft Corp. 1986
*/
#define INCL_DOSMISC
#include <os2def.h>
#include <bsedos.h>
int j = 0; /* zero variable for division */
main()
{
USHORT VecNum; /* Exception number (0,4,5,6,7,16) */
PFN PrevAddress; /* Storage for old vector address, used to
reset the vector when finished */
PFN Dummy; /* Dummy variable used when resetting vector */
int APIENTRY handler(); /* Name of routine that will handle exception */
int i = 9; /* Variable to be divided by 0 */
/* Set up handler for Exception 0, 'divide by zero' */
VecNum = 0;
DosSetVec(VecNum,handler,&PrevAddress);
/* Test the handler */
i = i/j;
printf("new i = %d\n", i);
/* Reset handler for exception 0 */
DosSetVec(VecNum,PrevAddress,&Dummy);
}
/*
* Handler subroutine for testing DosSetVec above.
* This is the routine that will get control
* when the exception occurs.
*/
int APIENTRY handler()
{
j = 3; /* Since j=0 caused this exception, setting j=3 will prevent
the exception from recurring, when we return */
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.