6.5 PE Output Format

Asmc Macro Assembler

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

Field32-bit Value64-bit Value (if different)
Signature "PE"
Machine 14Ch 8664h
Timestamp date & time
Size OptionalHeader 0E0h0F0h
Characteristics 10Fh12Fh
Magic 10Bh20Bh
LinkerVersion5.1
ImageBase400000h
SectionAlignment1000h
FileAlignment200h
OSVersion4.0
ImageVersion0.0
SubsystemVersion4.0
Win32Version0
Checksum0
Subsystem2 (=Console)
DllCharacteristics0
SizeOfStack100000h,1000h
SizeOfHeap100000h,1000h
LoaderFlags0

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.