Releases: qb40/exe-format
DOS EXE Format description by Microsoft Corporation.
INF: Executable-File Header Format [P_WinSDK]
3.00
WINDOWS
PSSONLY | Windows 3 Developers Notes softlib ENDUSER
Summary:
Note: This article is part of a set of seven articles, collectively
called the "Windows 3.00 Developer's Notes." More information about
the contents of the other articles, and procedures for ordering a
hard-copy set, can be found in the knowledge base article titled "INF:
The Windows 3.00 Developer's Notes" (Q65260).
This article can be found in the Software/Data Library by searching on
the word EXEFMT or S12688. EXEFMT was archived using the PKware
file-compression utility.
More Information:
Microsoft defined the segmented executable file format for Windows
applications and dynamic-link libraries (DLLs). This file format is
also referred to as the New Executable Format. This new format is an
extension of the existing MS-DOS .EXE format (old-style format). The
purpose of the segmented executable format is to provide the
information needed to support the dynamic linking and segmentation
capabilities of the Windows environment.
An executable file contains Microsoft Windows code and data, or
Windows code, data, and resources. Specific fields have been added to
the old-style .EXE format header to indicate the existence of the
segmented file format. The old-style header may contain a valid
executable program, called a stub program, that will be executed if
the program is run on MS-DOS (without Windows). This stub program
usually prints a message indicating that Microsoft Windows is required
to run the program. The segmented executable format extensions also
begin with a header that describes the contents and location of the
executable image in the file. The loader uses this header information
when it loads the executable segments in memory.
======================================================================
OLD-STYLE HEADER EXTENSIONS
The old-style header contains information the loader expects for a DOS
executable file. It describes a stub program (WINSTUB) the loader can
place in memory when necessary, it points to the new-style header, and
it contains the stub programs relocation table.
The following illustrates the distinct parts of the old-style
executable format:
+-------------------------+
00h | Old-style header info |
+-------------------------+
20h | Reserved |
+-------------------------+
3Ch | Offset to segmented |
| .EXE header |
+-------------------------+
40h | Relocation table and |
| DOS stub program |
+-------------------------+
| Segmented .EXE Header |
| . |
| . |
| . |
The word at offset 18h in the old-style .EXE header contains the
relative byte offset to the stub program's relocation table. If this
offset is 40h, then the double word at offset 3Ch is assumed to be the
relative byte offset from the beginning of the file to the beginning
of the segmented executable header. A new-format .EXE file is
identified if the segmented executable header contains a valid
signature. If the signature is not valid, the file is assumed to be an
old-style format .EXE file. The remainder of the old-style format
header will describe a DOS program, the stub. The stub may be any
valid program but will typically be a program that displays an error
message.
======================================================================
SEGMENTED EXE FORMAT
Because Windows executable files are often larger than one segment
(64K), additional information (that does not appear in the old-style
header) is required so that the loader can load each segment properly.
The segmented EXE format was developed to provide the loader with this
information.
The segmented .EXE file has the following format:
+-----------------+
00h | Old-style EXE |
| Header |
+-----------------+
20h | Reserved |
+-----------------+
3Ch | Offset to | ---+
| Segmented Header| |
+-----------------+ |
40h | Relocation Table| |
| & Stub Program | |
+-----------------+ |
| | |
+-----------------+ |
xxh | Segmented EXE | <--+
| Header |
+-----------------+
| Segment Table |
+-----------------+
| Resource Table |
+-----------------+
| Resident Name |
| Table |
+-----------------+
| Module Reference|
| Table |
+-----------------+
| Imported Names |
| Table |
+-----------------+
| Entry Table |
+-----------------+
| Non-Resident |
| Name Table |
+-----------------+
| Seg #1 Data |
| Seg #1 Info |
+-----------------+
.
.
.
+-----------------+
| Seg #n Data |
| Seg #n Info |
+-----------------+
The following sections describe each of the components that make up
the segmented EXE format. Each section contains a description of the
component and the fields in the structures that make up that
component.
Note: All unused fields and flag bits are reserved for future use and
must contain 0 (zero) values.
======================================================================
SEGMENTED EXE HEADER
The segmented EXE header contains general information about the EXE
file and contains information on the location and size of the other
sections. The Windows loader copies this section, along with other
data, into the module table in the system data. The module table is
internal data used by the loader to manage the loaded executable
modules in the system and to support dynamic linking.
The following describes the format of the segmented executable header.
For each field, the offset is given relative to the beginning of the
segmented header, the size of the field is defined, and a description
is given.
Offset Size Description
------ ---- -----------
00h DW Signature word.
"N" is low-order byte.
"E" is high-order byte.
02h DB Version number of the linker.
03h DB Revision number of the linker.
04h DW Entry Table file offset, relative to the beginning of
the segmented EXE header.
06h DW Number of bytes in the entry table.
08h DD 32-bit CRC of entire contents of file.
These words are taken as 00 during the calculation.
0Ch DW Flag word.
0000h = NOAUTODATA
0001h = SINGLEDATA (Shared automatic data segment)
0002h = MULTIPLEDATA (Instanced automatic data
segment)
2000h = Errors detected at link time, module will not
load.
8000h = Library module.
The SS:SP information is invalid, CS:IP points
to an initialization procedure that is called
with AX equal to the module handle. This
initialization procedure must perform a far
return to the caller, with AX not equal to
zero to indicate success, or AX equal to zero
to indicate failure to initialize. DS is set
to the library's data segment if the
SINGLEDATA flag is set. Otherwise, DS is set
to the caller's data segment.
A program or DLL can only contain dynamic
links to executable files that have this
library module flag set. One program cannot
dynamic-link to another program.
0Eh DW Segment number of automatic data segment.
This value is set to zero if SINGLEDATA and
MULTIPLEDATA flag bits are clear, NOAUTODATA is
indicated in the flags word.
A Segment number is an index into the module's segment
table. The first entry in the segment table is segment
number 1.
10h DW Initial size, in bytes, of dynamic heap added to the
data segment. This value is zero if no initial local
heap is allocated.
12h DW Initial size, in bytes, of stack added to the data
segment. This value is zero to indicate no initial
stack allocation, or when SS is not equal to DS.
14h DD Segment number:offset of CS:IP.
18h DD Segment number:offset of SS:SP.
If SS equals the automatic data segment and SP equals
zero, the stack pointer is set to the top of the
automatic data segment just below the additional heap
area.
+--------------------------+
| additional dynamic heap |
+--------------------------+ <- SP
| additional stack |
+--------------------------+
| loaded auto data segment |
+----...