When command.com is asked to execute a .com or .exe file, it will call the interrupt service 21h/AH=4B, the EXEC service. It is up to the calling program to:
- build a DOS EXEC parameter block (see http://www.delorie.com/djgpp/doc/rbinter/it/90/15.html )
(includes information on environment variables, command lines arguments, FCBs and register values on return)
- free up all memory the calling program isn't using
- setup calling argument registers
- ah = 4Bh ('EXEC' service type)
- al = 00h ('load and execute' function)
- ds:dx -> program name
- es:bx -> ptr to exec parameter block
- call interrupt 21h
- on return reset stack pointer and test for errors.
When interrupt 21h is called (here's where it gets hazy for me):
- a page aligned block of memory is allocated
- the file extension is ignored, instead DOS will check the first two bytes
of the file for signature "MZ" or "ZM" if an EXE, and no signature for COM.
for exe:
- exe header is read for initial register values
- copy code section from exe into memory
- relocation table (see http://en.wikipedia.org/wiki/Relocation_table) is read and
far pointers are adjusted in memory
- setup register values
- jump to CS:IP -> entry point (defined in exe header, relative to start of program)
for com:
- copy entire .com file into memory
- setup register values
- AL,AH drive letter status
- CS,DS,ES,SS -> PSP segment
- SP = offset of last word available in first 64k segment
- jump to IP=100h
Program should now be executing.
Notes:
In Microsoft's KB document "Order of Precedence in Locating Executable Files", it mentions the
use of "MS-DOS EXEC function (interrupt 21h service 4Bh)" for executing .com and .exe files
http://support.microsoft.com/kb/35284
So we can look at Ralph Brown's Interrupt List on Int 21/AH=4Bh
and an example of use:
and the dos exe header format:
(this is based off some googling, so please feel free to add suggestions)