How MS-DOS 6.22 Handles Interrupt 21h Vectoring
MS-DOS 6.22 relies on the x86 real-mode software interrupt mechanism to provide an interface between user-level programs and the operating system's underlying services. Interrupt 21h (INT 21h) serves as the primary Application Programming Interface (API) dispatcher for file access, memory management, process control, and console input/output. Understanding how MS-DOS 6.22 vectors this interrupt involves analyzing the Real Mode Interrupt Vector Table (IVT), the CPU's hardware interrupt sequence, internal DOS stack switching, and function dispatching based on CPU registers.
The Interrupt Vector Table (IVT) Setup
In the 16-bit real mode of MS-DOS 6.22, memory addresses
0000:0000h through 0000:03FFh are reserved for
the Interrupt Vector Table. The IVT contains 256 entries, each
consisting of a 4-byte far pointer (a 16-bit segment and a 16-bit
offset) pointing to the corresponding Interrupt Service Routine
(ISR).
The vector for INT 21h is located at memory address
0000:0084h (calculated as 21h * 4 = 84h).
During the boot process, when MSDOS.SYS initializes:
- The kernel loads its system routines into memory.
- The kernel sets the IVT entry at offset
0084hto point to the primary DOS entry point routine. - This vector remains active unless hooked or modified by a Terminate and Stay Resident (TSR) program, a debugger, or device driver.
Invocation and Processor-Level Context Switching
When a program requests a DOS service, it loads specific parameters
into general-purpose registers—most notably placing the service function
code into the AH register—and executes the
INT 21h instruction.
Upon encountering INT 21h, the x86 processor executes
the following hardware sequence:
- Pushes the 16-bit
FLAGSregister onto the current stack. - Clears the Interrupt Enable Flag (
IF) and the Trap Flag (TF), temporarily disabling maskable hardware interrupts to ensure atomic transition. - Pushes the current Code Segment (
CS) register onto the stack. - Pushes the current Instruction Pointer (
IP) register onto the stack. - Reads the 4-byte address from
0000:0084hintoIP(low word) andCS(high word), transferring execution directly to the MS-DOS kernel's entry point.
Kernel Entry and Stack Switching
MS-DOS 6.22 is fundamentally non-reentrant. Because the calling application's stack space might be limited or corrupted, the DOS ISR must carefully manage internal execution contexts:
- Reentrancy Check (InDOS Flag): The kernel
references its internal
InDOSvariable (tracked via an internal counter). If an interrupt occurs whileInDOSis already incremented, the kernel determines whether the call is safe or if it originates from a critical hardware event (like INT 08h or INT 09h). - Stack Swapping: The kernel preserves the caller's
Stack Segment (
SS) and Stack Pointer (SP) registers in internal variables and switches the processor to one of several internal DOS stacks (such as an auxiliary stack, an I/O stack, or an error stack). - Register Preservation: General-purpose registers
(
AX,BX,CX,DX,SI,DI,BP,DS,ES) are saved onto the stack so that their states can be preserved or selectively returned to the caller.
Function Dispatching via the Jump Table
Once the environment is stabilized, the entry point code isolates the
function number found in the AH register (and in some
extended calls, AL as a sub-function number):
- Range Validation: The kernel verifies that the
value in
AHfalls within the supported range of DOS API functions (functions00hthrough6Ch, alongside minor extensions). - Address Resolution: The kernel indexes an internal
jump table using the value in
AH. Each entry in the jump table contains the near address of the specific handler subroutine inside the DOS kernel code segment. - Branching: The dispatcher performs an indirect jump
to the target handler (for example, reading a file via Function
3Fhor terminating a program via Function4Ch).
Execution and Return Sequence
Once the specific function finishes its operations:
- Status Code Reporting: The handler updates status
indicators. Success or failure is often communicated by setting or
clearing the Carry Flag (
CF) within the saved image of the caller'sFLAGSregister on the stack. Return codes are placed intoAX. - Stack Restoration: The kernel decrements the
InDOSflag, restores the caller's originalSSandSPregisters, and restores the saved general-purpose registers (excluding those modified to return data). - IRET Execution: The handler terminates with an
IRET(Interrupt Return) instruction. The processor automatically popsIP,CS, and the modifiedFLAGSfrom the caller's stack, immediately resuming execution at the instruction directly following the originalINT 21hcall in the application.