Introduction
.exe is the extension for programs on MS-DOS, Windows and OS/2. Five
different formats have used it, each building on the ones before: the MS-DOS MZ format
from 1983, the 16-bit Windows NE format from 1985, the 32-bit LE and LX formats of
Windows device drivers, DOS extenders and OS/2, and the PE format used by 32-bit and
64-bit Windows since 1993.
All five start with the bytes MZ. Each newer format keeps a complete
MS-DOS program at the front of the file, the stub, so that running it under DOS prints a
message such as “This program cannot be run in DOS mode” instead of crashing. The real
header comes after the stub, and its position is stored at offset 0x3C.
The newer formats are also used for libraries and drivers, under extensions such as
.dll, .drv, .vxd and .sys.
Variations
| Format | Variation | About | Open |
|---|---|---|---|
.EXE | MS-DOS executable (MZ) | 16-bit DOS programs: an MZ header, relocations and the code. | Open |
.EXE | 16-bit Windows executable (NE) | Windows 3.x and early OS/2 programs and DLLs, in movable segments. | Open |
.EXE | Linear Executable (LE) | 32-bit Windows VxD drivers and DOS extender programs, in paged objects. | Open |
.EXE | OS/2 executable (LX) | 32-bit OS/2 programs and DLLs, in paged objects. | Open |
.EXE | Windows Portable Executable (PE) | 32-bit and 64-bit Windows programs and DLLs: headers, sections and imports. | Open |
MS-DOS executable (MZ)
The executable format of MS-DOS, used from DOS 2.0 in 1983 and named after the initials of Mark Zbikowski, one of its designers. An MZ program is 16-bit x86 code with a short header and a table of relocations, which DOS uses to adjust the program’s segment addresses to wherever it was loaded.
The file starts with MZ and has no second header. Either the relocation
table offset at 0x18 is below 0x40, or the 32-bit value at
0x3C does not point to NE, LE, LX
or PE\0\0 inside the file.
16-bit Windows executable (NE)
The New Executable format of 16-bit Windows, from Windows 1.0 to 3.11, and of the first versions of OS/2. It splits code and data into segments that can be loaded and moved on demand, imports functions from other modules by name or number, and stores resources such as icons, menus and dialogs inside the file.
The file starts with MZ, and the 32-bit offset at 0x3C
points to the bytes NE. Bit 15 of the flags word at offset
0x0C of the NE header is set for a library.
Linear Executable (LE)
A 32-bit format for code that runs in the flat memory of the 386. Windows 3.x and
Windows 95, 98 and Me use it for virtual device drivers (.vxd and
.386 files), and some DOS extenders, such as DOS/4GW, use it for 32-bit
DOS programs.
The file starts with MZ, and the 32-bit offset at 0x3C
points to the bytes LE.
OS/2 executable (LX)
The Linear eXecutable format of 32-bit OS/2, from OS/2 2.0 onwards, for programs
(.exe) and libraries (.dll). It is a close relative of LE,
with a few changes to how pages are stored.
The file starts with MZ, and the 32-bit offset at 0x3C
points to the bytes LX.
Windows Portable Executable (PE)
The format of programs and libraries on 32-bit and 64-bit Windows since Windows NT 3.1 in 1993, also used for UEFI firmware applications. Built on the COFF object format, it holds code and data in sections, with tables of imports, exports, resources and relocations that let Windows load it at any address.
The file starts with MZ, and the 32-bit offset at 0x3C
points to the four bytes PE\0\0. The optional header’s magic number,
0x10B or 0x20B, tells 32-bit from 64-bit, and the
IMAGE_FILE_DLL flag marks a library.
Links
Software
Reference
- PE Format, Microsoft’s specification, which also describes the MS-DOS stub