NASM - The Netwide Assembler

version 3.00rc15

Chapter 13: APX Instruction Syntax

Intel APX (Advanced Performance Extensions) introduces multiple new features, mostly to existing instructions. APX is only available in 64-bit mode.

See https://www.nasm.us/specs/apx for a link to the APX technical documentation. NASM generally follows the syntax specified in the Assembly Syntax Recommendations for Intel APX document although some syntax is relaxed, see below.

13.1 Extended General Purpose Registers (EGPRs)

When it comes to register size, the new registers (R16R31) work the same way as registers R8R15 (see also section 12.1):

Extended registers require that either a REX2 prefix (the default, if possible) or an EVEX prefix is used.

There are some instructions that don't support EGPRs. In that case, NASM will generate an error if they are used.

13.2 New Data Destination (NDD)

Using the new data destination register (when supported) is specified by adding an additional register in place of the first operand. For example an ADD instruction:

     add rax, rbx, rcx

... which would add RBX and RCX and store the result in RAX, without modifying neither RBX nor RCX.

13.3 Suppress Modifying Flags (NF)

The {nf} prefix on a supported instruction inhibits the update of the flags, for example:

     {nf} add rax, rbx

... will add RAX and RBX together, storing the result in RAX, while leaving the flags register unchanged.

NASM also allows the {nf} prefix (or any other curly-brace prefix) to be specified after the instruction mnemonic. Spaces around curly-brace prefixes are optional:

     {nf} add rax, rbx       ; Standard syntax 
     {nf}add  rax, rbx       ; Prefix without space 
     add {nf} rax, rbx       ; Suffix syntax 
     add{nf}  rax, rbx       ; Suffix without space

13.4 Zero Upper (ZU)

The {zu} prefix can be used meaning – "zero-upper", which disables retaining the upper parts of the registers and instead zero-extends the value into the full 64-bit register when the operand size is 8 or 16 bits (this is always done when the operand size is 32 bits, even without APX). For example:

     {zu} setb al

... zeroes out bits [63:8] of the RAX register. For this specific instruction, NASM also eccepts these alternate syntaxes:

     {zu} setb ax 
     setb {zu} al 
     setb {zu} ax 
     setb {zu} eax 
     setb {zu} rax 
     setb eax 
     setb rax

13.5 Source Condition Code (Scc) and Default Flags Value (DFV)

The source condition code (Scc) instructions, CCMPScc and CTESTScc, perform a test which if successful set the arithmetic flags to a user specfied value and otherwise leave them unchanged.

NASM allows the resulting default flags value to be specified either using the {dfv=}...} syntax, containing a comma-separated list of zero or more of the CPU flags OF, SF, ZF or CF or simply as a numeric immediate (with OF, SF, ZF and CF being represented by bits 3 to 0 in that order.)

The PF flag is always set to the same value as the CF flag, and the AF flag is always cleared. NASM allows {dfv=pf} as an alias for {dfv=cf}, but do note that it still affects both flags.

NASM allows, but does not require, a comma after the {dfv=} value; when using the immediate syntax a comma is required; these examples all produce the same instruction:

     ccmpl {dfv=of,cf} rdx, r30 
     ccmpl {dfv=of,cf}, rdx, r30 
     ccmpl 0x9, rdx, r30                     ; Comma required

The immediate syntax also allows for the {dfv=} values to be stored in a symbol, or having arithmetic done on them. Note that when used in an expression, or in contexts other than EQU or one of the Scc instructions, parenteses are required; this is a safety measure (programmer needs to explicitly indicate that use as an expression is what is intended):

     ccmpl ({dfv=of}|{dfv=cf}), rdx, r30     ; Parens, comma required 
ocf1 equ {dfv=of,cf}                         ; Parens not required 
     ccmpl ocf1, rdx, r30                    ; Comma required 
ofcf equ ({dfv=of,sf,cf} & ~{dfv=sf})        ; Parens required 
     ccmpl ofcf2, rdx, r30                   ; Comma required

13.6 PUSH and POP Extensions

APX adds variations of the PUSH and POP instructions that:

These extensions only apply to register forms; they are not supported for memory or immediate operands.

The standard syntax for (P)PUSH2 and (P)POP2 specify the registers in the order they are to be pushed and popped on the stack:

     push2p rax, rbx 
     ; rax in [rsp+8] 
     ; rbx is [rsp+0] 
     pop2p rbx, rax

... would be the equivalent of:

     push rax 
     push rbx 
     ; rax in [rsp+8] 
     ; rbx is [rsp+0] 
     pop rbx 
     pop rax

NASM also allows the registers to be specified as a register pair separated by a colon, in which case the order is always specified in the order high:low and thus is the same for PUSH2 and POP2. This means the order of the operands in the POP2 instruction is different:

     push2p rax:rbx 
     ; rax in [rsp+8] 
     ; rbx is [rsp+0] 
     pop2p rax:rbx

13.7 64-bit absolute jump (JMPABS)

A new near jump instruction takes a 64-bit absolute address immediate.

NASM allows this instruction to be specified either as:

     jmpabs target

... or:

     jmp abs target

The generated code is identical. The ABS is required regardless of the DEFAULT setting.

13.8 APX and the NASM optimizer

When the optimizer is enabled (see section 2.1.24), NASM may apply a number of optimizations, some of which may apply non-APX instructions to what otherwise would be APX forms. Some examples are:

13.9 Force APX Encoding

APX encoding, using REX2 and EVEX, respectively, can be forced by using the {rex2} or {evex} instruction prefixes.