How MS-DOS 6.22 Executes COM and EXE Files
MS-DOS 6.22 handles the execution of COM and EXE files using distinct loading mechanisms tailored to their differing internal architectures. COM files are simple, flat memory images constrained to a single 64KB segment, while EXE files are structured, relocatable executables capable of spanning multiple segments up to the limit of available conventional memory. When launching a program, DOS determines the file type, allocates memory, builds a Program Segment Prefix (PSP), sets the CPU registers to specific initial states, and hands execution over to the application.
File Identification and Priority
When a user enters a command without an extension, MS-DOS 6.22 searches the current directory and PATH in a strict order:
- Internal commands (e.g.,
DIR,COPY) .COMfiles.EXEfiles.BATfiles
Although the extension guides file discovery, MS-DOS does not rely
solely on the extension to determine the internal file format. Upon
opening the file, the operating system reads the first two bytes. If
these bytes match the ASCII characters "MZ" or "ZM"
(0x4D 0x5A or 0x5A 0x4D, named after MS-DOS
engineer Mark Zbikowski), MS-DOS processes the file as an EXE format
executable, even if it carries a .COM extension. If the
signature is absent, the file is treated as a flat COM binary.
Loading and Executing COM Files
The COM (Command) format is a direct carryover from CP/M-80, designed for simplicity and small memory footprints. It contains no file header, relocation data, or metadata—only raw, executable x86 machine code.
- Memory Allocation: MS-DOS 6.22 allocates a memory block for the COM file. By default, it allocates all available conventional memory in the largest free block (or up to 64KB if restricted), though the code, data, and stack combined cannot exceed 64KB. Because the file must fit inside a single segment alongside its overhead, the maximum size of a COM file on disk is roughly 65,280 bytes.
- Program Segment Prefix (PSP): DOS constructs a
256-byte (
100hbytes) PSP at the base of the allocated segment. The PSP contains the exit address, interrupt vectors, the Command Line Parameter table, and the File Handle Table. - Binary Image Loading: The entire contents of the
COM file are read directly from disk into memory, beginning immediately
after the PSP at offset
0100h. - Register Initialization:
- CS, DS, ES, SS: All four segment registers are set to point to the base segment containing the PSP.
- IP (Instruction Pointer): Set to
0100h, pointing to the start of the loaded program code. - SP (Stack Pointer): Set to the end of the 64KB
segment (usually
FFFEh), providing a working stack that grows downward toward the program code. If the segment is smaller than 64KB, SP is placed at the end of the allocated block. - A zero word (
0000h) is pushed onto the stack, allowing a simple near return (RET) instruction to trigger a jump to PSP offset0000h(which contains anINT 20hinstruction to exit back to DOS).
- Transfer: Control transfers directly to
CS:0100h.
Loading and Executing EXE Files
The EXE format (specifically the DOS MZ executable format) supports programs that require more than 64KB of memory, separating code, data, and stack into distinct segments.
- Header Parsing: MS-DOS reads the minimum 512-byte
header at the start of the file. The header contains:
- The "MZ" signature.
- The program size and header size.
- Relocation table offset and entry count.
- Minimum and maximum memory requirements (
MINALLOCandMAXALLOC). - Initial register values for
CS:IPandSS:SP.
- Memory Allocation: DOS allocates a block of memory
sized to fit the PSP, the load module, and at least the minimum extra
paragraphs defined in
MINALLOC. - PSP Creation: DOS places a 256-byte PSP at the beginning of the allocated block.
- Image Loading: The program code and data (the load module) are loaded immediately above the PSP.
- Relocation Processing: Because an EXE can be loaded at any arbitrary segment in memory, any hardcoded segment references within the code must be patched. DOS reads the relocation table from the EXE header, iterates through each pointer entry, and adds the base segment address of the load module to the word at each specified offset.
- Register Initialization:
- DS and ES: Point to the segment of the PSP, allowing the application to read command-line arguments and DOS environment data. The application is responsible for changing DS and ES to its own data segments if needed.
- CS:IP: Loaded with the initial values from the EXE header, with the load module base segment added to the header's CS value.
- SS:SP: Loaded with the initial values from the EXE header, with the load module base segment added to the header's SS value.
- Transfer: MS-DOS transfers execution via a far jump
or far call to the calculated initial
CS:IP.