7.5 Interrupt and Exception Handlers

Programs install interrupt and exception handlers to provide special responses to software interrupts, hardware interrupts, errors, or other conditions detected by the CPU. The handler determines what action to take. Most handlers carry out the action and return to the program at the point of the interruption, although some default handlers terminate the program that caused the interruption or exception.

In general, an interrupt or exception handler should do the following:

Save the registers it uses and restore them before returning.

Take precautions to avoid stack overflow. If a handler uses more than a few bytes of stack, it should use its own stack, restoring the original stack before returning.

Disable interrupts only when performing critical processing such as changing stacks or updating critical data. Enable the interrupts immediately after completing the task.

Use the iret instruction to return.

When the handler receives control, the SS:SP registers point to whatever stack was active when the interrupt or exception occurred. This could be a stack belonging to MS-DOS, to a program, or to other software. A handler that uses more than a few bytes of stack should switch to its own stack.

To install an interrupt or exception handler, a program must use the following procedure:

1.Retrieve the address of the current handler by using Get Interrupt Vector (Interrupt 21h Function 35h).

2.Save the address of the current handler. Before terminating, the program must restore this handler by using Set Interrupt Vector (Interrupt 21h Function 25h).

3.Install the new handler by using Set Interrupt Vector.

Programs that install interrupt or exception handlers must restore the original handlers before terminating. Since the default (MS-DOS) CTRL+C and critical-error handlers (Interrupts 23h and 24h) terminate programs without restoring interrupts, programs that install new handlers must also install custom handlers for Interrupts 23h and 24h. The custom Interrupt 23h and Interrupt 24h handlers must determine whether the program that installed the new handler is about to terminate; if it is, they must restore the original interrupt handlers before the program terminates. Note that MS-DOS automatically restores the original Interrupt 23h and Interrupt 24h handlers.

In general, if an interrupt occurs while a program is running, the corresponding interrupt handler can use any MS-DOS system function. In any other case, the handler can use only the character I/O functions (Interrupt 21h Functions 01h through 0Ch). For example, if a divide-error exception occurs in a program, the divide-error handler can display a message by using Write File or Device (Interrupt 21h Function 40h). However, if the error occurs in MS-DOS, the handler must use a character I/O function, such as Display String (Interrupt 21h Function 09h). If a critical disk error is being processed, the handler must not use any MS-DOS system function.

A handler can determine whether an interrupt or exception occurred in MS-DOS by examining the InDOS flag. If MS-DOS is processing a system function, this one-byte flag is nonzero. The handler can retrieve the address of the InDOS flag by using Get InDOS Flag Address (Interrupt 21h Function 34h). The handler can determine whether a critical disk error is being processed by examing the ErrorMode flag (the byte immediately before the InDOS flag). If the ErrorMode flag is nonzero, MS-DOS is processing a critical disk error.

Although a program can install interrupt handlers that service hardware interrupts, these handlers are device-specific and are not guaranteed to work with all MS-DOS computers. To support hardware interrupts, the program installs an interrupt service routine (ISR) and either programs the computer's interrupt controller to support interrupts from the specified device or uses interrupts defined by the device's ROM BIOS. In either case, the information required to carry out these steps is beyond the scope of this book.