mirror of
https://github.com/netwide-assembler/nasm.git
synced 2025-10-10 00:25:06 -04:00
doc: Move APX doc to the syntax doc
The syntax chapter is supposed to be about concepts or instructions that either have a lot of different syntaxes or new/odd ones. Signed-off-by: Maciej Wieczor-Retman <maciej.wieczor-retman@intel.com>
This commit is contained in:
243
doc/syntax.src
Normal file
243
doc/syntax.src
Normal file
@@ -0,0 +1,243 @@
|
||||
\C{Syntax} Syntax Quirks and Summaries
|
||||
|
||||
\H{APX} \I{apx syntax}\i{APX} Instruction Syntax
|
||||
|
||||
Intel APX (\i{Advanced Performance Extensions}) introduces multiple
|
||||
new features, mostly to existing instructions. APX is only available
|
||||
in 64-bit mode.
|
||||
|
||||
\b There are 16 new general purpose registers, \c{R16} to \c{R31}.
|
||||
|
||||
\b Many instructions now support a non-destructive destination
|
||||
operand.
|
||||
|
||||
\b The ability to suppress the setting of the arithmetic flags.
|
||||
|
||||
\b The ability to zero the upper parts of a full 64-bit register for
|
||||
8- and 16-bit operation size instructions. (This zeroing is always
|
||||
performed for 32-bit operations; this has been the case since 64-bit
|
||||
mode was first introduced.)
|
||||
|
||||
\b New instructions to conditionally set the arithmetic flags to a
|
||||
user-specified value.
|
||||
|
||||
\b Performance-enhanced versions of the \c{PUSH} and \c{POP}
|
||||
instructions.
|
||||
|
||||
\b A 64-bit absolute jump instruction.
|
||||
|
||||
\b A new \i{REX2} prefix.
|
||||
|
||||
See \w{https://www.nasm.us/specs/apx} for a link to the APX technical
|
||||
documentation. NASM generally follows the syntax specified in the
|
||||
\e{Assembly Syntax Recommendations for Intel APX} document although
|
||||
some syntax is relaxed, see below.
|
||||
|
||||
\S{egprs} \i{Extended General Purpose Registers} (\i{EGPRs})
|
||||
|
||||
When it comes to register size, the new registers (\c{R16}-\c{R31})
|
||||
work the same way as registers \c{R8}-\c{R15} (see also \k{reg64}):
|
||||
|
||||
\b \c{R31} is the 64-bit form of register 31,
|
||||
|
||||
\b \c{R31D} is the 32-bit form,
|
||||
|
||||
\b \c{R31W} is the 16-bit form, and
|
||||
|
||||
\b \c{R31B} is the 8-bit form. The form \c{R31L} can also be used if
|
||||
the \c{altreg} macro package is used (\c{%use altreg}), see
|
||||
\k{pkg_altreg}.
|
||||
|
||||
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.
|
||||
|
||||
|
||||
\S{apx_ndd} \i{New Data Destination} (\i{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 \c{ADD} instruction:
|
||||
|
||||
\c add rax, rbx, rcx
|
||||
|
||||
... which would add \c{RBX} and \c{RCX} and store the result in
|
||||
\c{RAX}, without modifying neither \c{RBX} nor \c{RCX}.
|
||||
|
||||
\S{apx_nf} Suppress Modifying Flags (\i{NF})
|
||||
|
||||
The \c{\{nf\}} prefix on a supported instruction inhibits the update
|
||||
of the flags, for example:
|
||||
|
||||
\c {nf} add rax, rbx
|
||||
|
||||
... will add \c{RAX} and \c{RBX} together, storing the result in
|
||||
\c{RAX}, while leaving the flags register unchanged.
|
||||
|
||||
NASM also allows the \c{\{nf\}} prefix (or any other curly-brace
|
||||
prefix) to be specified \e{after} the instruction mnemonic. Spaces
|
||||
around curly-brace prefixes are optional:
|
||||
|
||||
\c {nf} add rax, rbx ; Standard syntax
|
||||
\c {nf}add rax, rbx ; Prefix without space
|
||||
\c add {nf} rax, rbx ; Suffix syntax
|
||||
\c add{nf} rax, rbx ; Suffix without space
|
||||
|
||||
|
||||
\S{apx_zu} \i{Zero Upper} (\i{ZU})
|
||||
|
||||
The \c{\{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:
|
||||
|
||||
\c {zu} setb al
|
||||
|
||||
... zeroes out bits [63:8] of the \c{RAX} register. For this specific
|
||||
instruction, NASM also eccepts these alternate syntaxes:
|
||||
|
||||
\c {zu} setb ax
|
||||
\c setb {zu} al
|
||||
\c setb {zu} ax
|
||||
\c setb {zu} eax
|
||||
\c setb {zu} rax
|
||||
\c setb eax
|
||||
\c setb rax
|
||||
|
||||
\S{apx_dfv} \i{Source Condition Code} (\I{scc}S\e{cc}) and \i{Default Flags
|
||||
Value} (\i{DFV})
|
||||
|
||||
The source condition code (S\e{cc}) instructions, \c{CCMPS}\e{cc} and
|
||||
\c{CTESTS}\c{cc}, perform a test which if successful set the
|
||||
arithmetic flags to a user specfied value and otherwise leave them
|
||||
unchanged.
|
||||
|
||||
NASM allows the resulting \e{default flags value} to be specified
|
||||
either using the \I\c{\{dfv=\}}\c{\{dfv=\}}...\c{\}} syntax,
|
||||
containing a comma-separated list of zero or more of the CPU flags
|
||||
\c{OF}, \c{SF}, \c{ZF} or \c{CF} or simply as a numeric immediate
|
||||
(with \c{OF}, \c{SF}, \c{ZF} and \c{CF} being represented by bits 3 to
|
||||
0 in that order.)
|
||||
|
||||
The \c{PF} flag is always set to the same value as the \c{CF} flag,
|
||||
and the \c{AF} flag is always cleared. NASM allows \c{\{dfv=pf\}} as
|
||||
an alias for \c{\{dfv=cf\}}, but do note that it still affects both
|
||||
flags.
|
||||
|
||||
NASM allows, but does not require, a comma after the \c{\{dfv=\}}
|
||||
value; when using the immediate syntax a comma is required; these
|
||||
examples all produce the same instruction:
|
||||
|
||||
\c ccmpl {dfv=of,cf} rdx, r30
|
||||
\c ccmpl {dfv=of,cf}, rdx, r30
|
||||
\c ccmpl 0x9, rdx, r30 ; Comma required
|
||||
|
||||
The immediate syntax also allows for the \c{\{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 \c{EQU} or one of the
|
||||
\c{S}\e{cc} instructions, parenteses are required; this is a safety
|
||||
measure (programmer needs to explicitly indicate that use as an
|
||||
expression is what is intended):
|
||||
|
||||
\c ccmpl ({dfv=of}|{dfv=cf}), rdx, r30 ; Parens, comma required
|
||||
\c ocf1 equ {dfv=of,cf} ; Parens not required
|
||||
\c ccmpl ocf1, rdx, r30 ; Comma required
|
||||
\c ofcf equ ({dfv=of,sf,cf} & ~{dfv=sf}) ; Parens required
|
||||
\c ccmpl ofcf2, rdx, r30 ; Comma required
|
||||
|
||||
|
||||
\S{apx_pushpop} \c{PUSH} and \c{POP} Extensions
|
||||
|
||||
APX adds variations of the \c{PUSH} and \c{POP} instructions that:
|
||||
|
||||
\b informs the CPU that a specific \c{PUSH} and \c{POP} constitute a
|
||||
matched pair, allowing the hardware to optimize for this common use
|
||||
case: \i\c{PUSHP} and \i\c{POPP};
|
||||
|
||||
\b operates on two registers at the same time: \i\c{PUSH2} and
|
||||
\i\c{POP2}, with paired variants \i\c{PUSH2P} and \i\c{POP2P}.
|
||||
|
||||
These extensions only apply to register forms; they are not supported
|
||||
for memory or immediate operands.
|
||||
|
||||
The standard syntax for (\c{P})\c{PUSH2} and (\c{P})\c{POP2} specify
|
||||
the registers in the order they are to be pushed and popped on the
|
||||
stack:
|
||||
|
||||
\c push2p rax, rbx
|
||||
\c ; rax in [rsp+8]
|
||||
\c ; rbx is [rsp+0]
|
||||
\c pop2p rbx, rax
|
||||
|
||||
... would be the equivalent of:
|
||||
|
||||
\c push rax
|
||||
\c push rbx
|
||||
\c ; rax in [rsp+8]
|
||||
\c ; rbx is [rsp+0]
|
||||
\c pop rbx
|
||||
\c pop rax
|
||||
|
||||
NASM also allows the registers to be specified as a \e{register pair}
|
||||
separated by a colon, in which case the order is always specified in
|
||||
the order \e{high}\c{:}\e{low} and thus is the same for \c{PUSH2} and
|
||||
\c{POP2}. This means the order of the operands in the \c{POP2}
|
||||
instruction is different:
|
||||
|
||||
\c push2p rax:rbx
|
||||
\c ; rax in [rsp+8]
|
||||
\c ; rbx is [rsp+0]
|
||||
\c pop2p rax:rbx
|
||||
|
||||
\S{apx_jmpabs} 64-bit absolute jump (\i\c{JMPABS})
|
||||
|
||||
A new near jump instruction takes a 64-bit \e{absolute} address
|
||||
immediate.
|
||||
|
||||
NASM allows this instruction to be specified either as:
|
||||
|
||||
\c jmpabs target
|
||||
|
||||
... or:
|
||||
|
||||
\c jmp abs target
|
||||
|
||||
The generated code is identical. The \c{ABS} is required regardless of
|
||||
the \c{DEFAULT} setting.
|
||||
|
||||
\S{apx_opt} \I{apx optimizer}APX and the NASM optimizer
|
||||
|
||||
When the optimizer is enabled (see \k{opt-O}), 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:
|
||||
|
||||
\b The \c{\{nf\}} prefix may be ignored on instructions that already
|
||||
don't modify the arithmetic flags.
|
||||
|
||||
\b When the \c{\{nf\}} prefix is specified, NASM may generate another
|
||||
instruction which would not modify the flags register. For example,
|
||||
\c{\{nf\} ror rax, rcx, 3} can be translated into
|
||||
\c{rorx rax, rcx, 3}.
|
||||
|
||||
\b The \c{\{zu\}} prefix may be ignored on instruction that already
|
||||
zero the upper parts of the destination register.
|
||||
|
||||
\b When the \c{\{zu\}} prefix is specified, NASM may generate another
|
||||
instruction which would zero the upper part of the register. For
|
||||
example, \c{\{zu\} mov ax, cs} can be translated into \c{mov eax, cs}.
|
||||
|
||||
\b New data destination or nondestructive source operands may be
|
||||
contracted if they are the same (and the semantics are otherwise
|
||||
identical). For example, \c{add eax, eax, edx} could be encoded as
|
||||
\c{add eax, edx} using legacy encoding. \e{NASM does not perform
|
||||
this optimization as of version 3.00, but it probably will in the
|
||||
future.}
|
||||
|
||||
|
||||
\S{apx_force} Force APX Encoding
|
||||
|
||||
APX encoding, using REX2 and EVEX, respectively, can be forced by
|
||||
using the \i\c{\{rex2\}} or \i\c{\{evex\}} instruction prefixes.
|
Reference in New Issue
Block a user