6.5 PE Output Format
The ( Windows ) PE output format ( both 32- and 64-bit ) is a binary format - there's no link step supposed to follow the assembly step. Hence all references must be resolved internally, no external references are possible. Since the Windows ABI is implemented as a set of dlls that export function names, it's necessary to provide a mechanism to call such external functions - in the PE format this is achieved with the help of directive OPTION DLLIMPORT; it allows to attach a module name to function prototypes used by the assembly source and consequently give the assembler the means to resolve all references without the help of a linker.The PE format requires a .MODEL FLAT directive in the source code. This directive will trigger the creation of the internal PE-header section, the value of the cpu at this time will determine whether a 32- or 64-bit PE binary is to be written.
As in all binary formats, the listing will contain a binary map; see Binary Output Format for more details.
If -pe is set, a few sections will be created internally:
- -.hdr$1 : section will contain the DOS MZ-stub.
- -.hdr$2 : section will contain the PE header
- -.hdr$3 : section will contain the PE object table
The default values in the PE header are
Field | 32-bit Value | 64-bit Value (if different) |
---|---|---|
Signature | "PE" | |
Machine | 14Ch | 8664h |
Timestamp | date & time | |
Size OptionalHeader | 0E0h | 0F0h |
Characteristics | 10Fh | 12Fh |
Magic | 10Bh | 20Bh |
LinkerVersion | 5.1 | |
ImageBase | 400000h | |
SectionAlignment | 1000h | |
FileAlignment | 200h | |
OSVersion | 4.0 | |
ImageVersion | 0.0 | |
SubsystemVersion | 4.0 | |
Win32Version | 0 | |
Checksum | 0 | |
Subsystem | 2 (=Console) | |
DllCharacteristics | 0 | |
SizeOfStack | 100000h,1000h | |
SizeOfHeap | 100000h,1000h | |
LoaderFlags | 0 |
To change the default values in the PE header there are two options. First, a predefined assembly-time variable @pe_file_flags will map the value of field Characteristics - changing the value of @pe_file_flags will also change the value in the header field. The other fields in the PE header are only accessible by setting the appropriate values in section .hdr$2. Fields not listed in the table above are set internally by the assembler to ensure data integrity and cannot be modified from within the assembly source.
If the PE binary is to use resources, a .rsrc section has to be created which is to contain them. Defining the resources manually works and is doable, but it might become tedious if a lot of resource items are to be defined. Therefore tool res2inc is supplied, which allows to convert a compiled resource file (.RES) to an assembly include file.
If a dll is created with -pe, one has to mark all procedures that are to be exported with the EXPORT attribute. If the exported names are to be undecorated, use the -zze cmdline option.
Sample Win64_8 shows how a 64-bit Windows binary is created with -pe. It also shows how to define resources in .rsrc manually and how to modify default values of PE header fields.