MS-DOS INT 21h Dispatcher: Core Design for Hardware‑Independent PC Applications
Describes how the INT 21h API provided a stable interface for file and process services, enabling applications to run unchanged across IBM PC‑compatible hardware.
10 Jan 2026, 01:09 UTC

Requirements
\nApplications needed a stable, hardware‑independent way to perform file I/O, load programs, and access devices without knowing the underlying disk controller, memory layout, or BIOS variations.
\nSmallest Suitable Design
\nThe DOS kernel implements an INT 21h dispatcher that reads the AH register to select a subfunction. Each subfunction calls a minimal routine built on top of DOS BIOS (INT 13h disk services) and the DOS BIOS for character I/O.
\nTrust and Data Boundaries
\nDOS runs in real mode with no hardware memory protection. The trust boundary is the software contract of INT 21h: callers must pass correct parameters (valid handles, properly formatted FCBs or PSPs) and the kernel returns error codes in AX and the Carry flag. Data integrity relies on well‑behaved programs respecting these contracts.
\nOperational Checks
\nBefore servicing a request the kernel validates the handle range, checks FCB format, verifies drive letters, and queries drive readiness via INT 13h. Errors such as invalid handle, file not found, or media change are reported through AX and the Carry flag.
\nFailure Modes
\n- \n
- Corrupted FAT or directory structures cause read/write failures. \n
- A missing or replaced COMMAND.COM can break the command line interpreter. \n
- A TSR that incorrectly hooks INT 21h may create infinite loops or corrupt the dispatcher. \n
- Exceeding the 640 KB conventional memory limit leads to allocation failures for new PSPs or file buffers. \n
Conditions That Would Change the Design
\n- \n
- Adoption of protected‑mode DOS extenders would require a new API to access extended memory. \n
- Migration to FAT32 would need support for larger cluster sizes and 32‑bit sector fields. \n
- Introduction of Windows‑style GUI subsystems would demand a layered interface that coexists with message passing. \n
Example: Minimal Assembly Program to Open a File
\nThe following program (not executed) demonstrates the documented INT 21h subfunction AH=3Dh (open file) using a handle‑based interface. It assumes DS points to the PSP and that a null‑terminated filename resides at filename.
\n mov ah, 3Dh ; open file\n mov al, 0 ; read‑only mode\n mov dx, offset filename ; pointer to filename\n int 21h\n jc open_error ; Carry set → error in AX\n ; file handle returned in AX\n ; ... use handle ...\n jmp done\nopen_error:\n ; AX contains DOS error code\ndone:\n\nTo verify the dispatcher is present, examine the interrupt vector table with DEBUG.COM:
\n\n DEBUG\n -d 0:4c\n\nThe four bytes at 0000:004c should contain the segment:offset of the INT 21h handler.
\nPractical Check
\nAfter assembling and linking the example, run it on a MS‑DOS 5.0 system. If the file exists and is accessible, the program will return with Carry clear and a non‑zero handle in AX. If the file is missing, AX will contain error code 02h (file not found) and Carry will be set. Observing these results confirms that the INT 21h dispatcher is correctly routing the call and returning documented error codes.
\nLimitations
\nThe INT 21h interface does not provide built‑in memory protection, long file names, or support for disks larger than 32 MB without extensions. Programs that rely on undocumented side effects may fail on later DOS versions or non‑IBM clones.
\n0 replies
A thoughtful contribution can make all the difference. Be the first to share one.