ExeHeaderRec Offset Size Contents ▀▀▀▀▀▀ ▀▀▀▀ ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +0 2 wSignature 5a4dH .EXE file signature ('MZ') +2 2 wPartPage length of partial page at end (generally ignored) +4 2 wPageCnt length of image in 512-byte pages, incl. header +6 2 wReloCnt number of items in relocation table +8 2 wHdrSize size of header in 16-byte paragraphs +0aH 2 wMinAlloc minimum RAM needed above end of prog (paragraphs) +0cH 2 wMaxAlloc maximum RAM needed above end of prog (paragraphs) +0eH 2 wInitSS segment offset of stack segment (for setting SS) +10H 2 wInitSP value for SP register when started +12H 2 wChkSum file checksum (negative sum of all words in file) +14H 2 wInitIP value for IP register when started +16H 2 wInitCS segment offset of code segment (for setting CS) +18H 2 wTablOff file-offset of first relo item (often 001cH) +1aH 2 wOverlayNo overlay number (0 for base module) 28 size of formatted portion of EXE header +? 4*? alReloTbl variable-length relocation table +? ? abFiller filler to paragraph boundary +? ? abImage start of program image Since an EXE file may be loaded on any segment, all absolute segment references (such as FAR CALLs, long address pointers, and references such as MOV AX,data_seg) must be adjusted to work for the memory location in which they are loaded. Here are the steps used by the DOS program loader (fn 4bH ) to load an EXE file: 1. Create a PSP via DOS Fn 26H. 2. Read 1cH bytes of the EXE file (the formatted portion of the EXE header) into a local memory area. 3. Determine the load module size: size=((wPageCnt*512)-(wHdrSize*16))-wPartPage 4. Determine file offset of load module = (wHdrSize * 16) 5. Select a segment addr, START_SEG, for loading (usually PSP+10H) 6. Allocate enough memory to hold the load module, honoring the settings in wMaxMem and wMinMem. 7. Read the load module into memory starting at START_SEG:0000 8. LSEEK to the start of the relocation table (wTablOff) 9. For each relocation item (wReloCnt): a. read the item as two 16-bit words (I_OFF,I_SEG) b. add RELO_SEG=START_SEG+I_SEG (find the address of relocation ref) c. fetch the word at RELO_SEG:I_OFF (read current value) d. add START_SEG to that word (perform the segment fixup) e. store the sum back at its original address (RELO_SEG:I_OFF) 10. Allocate memory for the program according to wMaxMem and wMinMem 11. Initialize registers and execute the program: a. ES = DS = PSP b. Set AX to indicate the validity of drive IDs in command line c. SS = START_SEG+ReloSS, SP = ExeSP d. CS = START_SEG+ReloCS, IP = ExeIP Note: Recent additions to the EXE format, specifically the CodeView, OS/2, and Windows versions of the EXE file contain additional information embedded in the executable file. Sorry, but these additions are not covered here. See Also: Program Startup & Exit Process Control Functions PSP: Program Segment Prefix DOS Environment -♦-