6.3 Win64 Output Format

Asmc Macro Assembler

6.3 Win64 Output Format

6.3.1 Win64 Basics

This output format, that is selected with the -win64 commandline option, is a variant of the COFF output format. It's commonly used to create object modules for 64-bit Windows. The default calling convention is the Win64 FASTCALL implementation.

6.3.2 Directive INVOKE in Win64

Unlike the 64-bit version of Masm, which doesn't support INVOKE anymore, JWasm still does; however, please be aware of some peculiarities:
  • in theory, using INVOKE requires the FRAME attribute for PROC. It will work without FRAME, but Win64 SEH won't be happy with it then.
  • the default implementation in 64-bit is very simple: for each INVOKE register RSP is reduced by the space required for the arguments, then the call is issued and finally register RSP is restored. To enable a more efficient code generation see OPTION WIN64, INVOKE Stack Space Reservation - this option is not active as default because it virtually requires a certain programming style.
  • there is no additional check that the stack is aligned to 16 byte. The PROC's FRAME attribute ensures that the stack is correctly aligned after the prologue is done. However, it's the programmers responsibility that the stack is still aligned when the code generated by INVOKE starts.
  • parameter names listed behind the PROC directive will always refer to the parameter's shadow space on the stack. However, on a procedure's entry the actual values of the first four parameters are hold in registers, and the value of the associated shadow spaces are undefined. See OPTION WIN64, Store Register Arguments, how to make JWasm automatically save the register arguments and thus initialize the shadow space on a procedure's entry.

6.3.3 Win64 Structured Exception Handling (SEH)

SEH in Win64 differs significantly from the implementation in Win32. It's very well possible to ignore Win64 SEH for assembly. However, if an assembly routine wants to comply to these rules, a thorough understanding of the Win64 ABI is necessary. Masm ( the 64-bit version ) supplies some "primitives" for SEH support (.ALLOCSTACK, .PUSHREG, .SAVEREG, ...), along with a new FRAME attribute for the PROC directive. These features are also supported by JWasm. See sample Win64_3 how the "primitives" are to be used for SEH support.

The big disadvantage is that using the FRAME keyword in Masm "disables" most of the other high level features combined with PROC (function parameters, locals and registers saved with USES) because no function prologues and epilogues are generated anymore. Additionally, the implementation at least in Masm v8 seems to be a bit buggy, at least in Masm v8. Because of this and to ease the usage of SEH in Win64 there is a new directive implemented in JWasm:

 
        OPTION FRAME:AUTO

If this option is set, JWasm will create Win64 SEH-compatible prologues and epilogues. If the option is off, JWasm will behave Masm-compatible, that is, FRAME found in a PROC directive will disable automatic prologue/epilogue generation. See sample Win64_3e how this option is supposed to be used.

As for the PROC syntax: The Masm documentation states that FRAME can be used in combination with USES and procedure parameters and must be located behind all parameters. However, this syntax isn't accepted by any Masm version. The only syntax which Masm will accept without being confused is FRAME as the one and only parameter for PROC. Therefore JWasm doesn't follow the Masm documentation in this point: the optional FRAME keyword is expected *before* the procedure parameters. The syntax in JWasm is:

 
    procname PROC [public] FRAME[:exc_handler] [USES <reglist>] [parameters]

The SEH "primitives" will generate some additional data in segments .pdata and .xdata. This data is somewhat hidden, but JWasm will display the corresponding data definitions in the listing if option -Sg is set.

Finally, JWasm's default behavior of INVOKE isn't fully SEH-compatible, because the stack pointer is temporarily changed to make room for arguments. To make INVOKE comply to SEH, OPTION WIN64 INVOKE Stack Space Reservation has to be used.