0
0
mirror of https://github.com/netwide-assembler/nasm.git synced 2025-10-10 00:25:06 -04:00
Files
nasm/doc/syntax.src
H. Peter Anvin f7e91f7868 doc: document %use vtern, minor tidying of the syntax chapter
Document the "vtern" macro package, and do some quite minor tidying of
the syntax chapter.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-09-29 20:47:18 -07:00

412 lines
15 KiB
Plaintext

\C{Syntax} Syntax Quirks and Summaries
\H{jumpcall} Summary of the \c{JMP} and \c{CALL} Syntax
The \i\c{JMP} and \i\c{CALL} instructions support a variety of syntaxes to
simplify their specific use cases. Some of the following chapters explain how
these two instructions interact with various special symbols that NASM uses and
some document non-obvious scenarios regarding differently sized modes of
operation.
\S{labeljmps} \i{Near Jump}s
Near jumps are jumps within a single segment. Probably the most common way to
use them is through labels, as explained in \k{locallab}. \i\c{APX} added a near
jump instruction - \I\c{JMPABS}, that allows jumps to any \I{64-bit
immediate}64-bit address specified with an immediate operand. The instruction
works with absolute addresses and the syntax options are shown in
\k{jmpabs}.
\S{jumploop} \i{Infinite Loop} Trick
One of the ways to quickly implement an infinite loop is using the \I{$,
here}\c{$} token which evaluates to the current position in the code. So a one
line infinite loop can simply look like:
\c jmp $
\S{mixsizejmpsum} Jumps and Mixed Sizes
\I{jumps, mixed-size}In some special circumstances one might need to jump
between 16-bit mode and 32-bit mode. \I{addressing, mixed-size}\I{mixed-size
addressing}A similar issue is addressing between 16 and 32 bit segments. The
possible cases and the relevant syntax for both problems are explained in
\k{mixjump} and \k{mixaddr} respectively.
\S{callprocoutlib} Calling Procedures Outside of a Shared Library
When writing shared libraries it's often necessary to call external code. In the
ELF format the \I\c{WRT} keyword takes on a different meaning than normally when
it helps reference a segment - it's used to refer to some special symbols (more
about it can be found in \k{win64pic}). In the case described here, "\c{wrt}
\i\c{..plt}" references a \i{PLT} (\i{procedure linkage table}) entry. It can be
used to call external routines in a way explained in \k{picproc}.
\S{farcall} \I{far call}\I{far jmp}\c{FAR} Calls and Jumps
NASM supports \c{FAR} (inter-segment) calls and jumps by means of the
syntax \c{call segment:offset}, where \c{segment} and \c{offset}
both represent immediate values. So to call a far procedure, you
could code either of
\c call (seg procedure):procedure
\c call weird_seg:(procedure wrt weird_seg)
(The parentheses are included for clarity, to show the intended
parsing of the above instructions. They are not necessary in
practice.)
NASM also supports the syntax \I\c{CALL FAR}\c{call far procedure} as
a synonym for the first of the above usages. \c{JMP} works identically
to \c{CALL} in these examples.
To declare a \i{far pointer} to a data item in a data segment, you
must code
\c dw symbol, seg symbol ; 16 bit
\c dd symbol, word seg symbol ; 32 bit
NASM supports no convenient synonym for this, though you can always
invent one using the macro processor.
\S{jmpabs} 64-bit absolute jump (\i\c{JMPABS})
Defined as part of the APX specification, \c{JMPABS} is a new near
jump instruction takes a 64-bit \e{absolute} address immediate. It is
the only \e{direct} jump instruction that can jump anywhere in the
address space in 64-bit mode.
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.
\H{shortnddnds} Compact \i{NDS}/\i{NDD} Operands
Some instructions that use the \i\c{VEX} prefix, mainly AVX ones, use
NDS (\i{Non-Destructive Source}) or NDD (\i{New Data Destination})
operands. Semantically it works by passing another operand to the
instruction so that none of the source operands are modified as a
result of the operation.
Syntatically NASM allows both the obvious format mentioned above and a
\i{compact format} - compact meaning that if a user passes two
operands instead of three, one of them is simply copied to be used as
the source or destination. Thereby these instructions have exactly
the same encoding:
\c vaddpd xmm0, xmm0, xmm1
\c vaddpd xmm0, xmm1
Here the \c{XMM0} register is used as the "non-destructive
source" even though in this case it will of course be modified.
\H{64moff} 64-bit \I{moffs}\e{moffs}
The \e{moffs} operand can be used with the \c{MOV} instruction, only
using the "\c{A}" register (\c{AL}, \c{AX}, \c{EAX}, or \c{RAX}), and
for non-64-bit operand size means to address memory at an offset from
a segment. For \I{64-bit immediate}64-bit operands it simply accesses
memory at a specified offset (since segment based addressing is mostly
unavailable in 64-bit mode). Syntax to use 64-bit offsets to address
memory is showcased in \k{id64disp}.
\H{spliteas} \i{Split EA} Addressing Syntax
Instructions that use the mib operand, (that is memory addressed with a base
register, with some offset, with an added index register that's multiplied by
some scale factor) can also utilize the split EA (\I{effective
addresses}effective addressing). The new form is mainly intended for MPX
instructions that use the \i{mib} operands, but can be used for any memory
reference. The basic concept of this form is splitting base and index:
\c mov eax,[ebx+8,ecx*4] ; ebx=base, ecx=index, 4=scale, 8=disp
NASM supports all currently possible forms of the mib syntax:
\c ; bndstx
\c ; next 5 lines are parsed same
\c ; base=rax, index=rbx, scale=1, displacement=3
\c bndstx [rax+0x3,rbx], bnd0 ; NASM - split EA
\c bndstx [rbx*1+rax+0x3], bnd0 ; GAS - '*1' indecates an index reg
\c bndstx [rax+rbx+3], bnd0 ; GAS - without hints
\c bndstx [rax+0x3], bnd0, rbx ; ICC-1
\c bndstx [rax+0x3], rbx, bnd0 ; ICC-2
\H{ternarylogic} No Syntax for Ternary Logic Instruction
\i\c{VPTERNLOGD} and \i\c{VPTERNLOGQ} are instructions that implement
an arbitrary logic function for three inputs. They take three register
operands and one immediate value that determines what logic function
the instruction shall implement on execution. Specifically the output
of the desired logic function is encoded in the immediate 8-bit
operand. 3 binary inputs can be configured in 8 possible ways giving 8
output bits that could implement any one of 256 possible logic
functions. Therefore it's not practical to have any syntax around
different possible logic functions.
However there are some macro solutions that can help avoid writing out truth
tables in order to use the ternary logic instructions. The simple, more manual
way is to calculate the logic operation encoding on the fly with a few lines of
arithmetic directives:
\c a equ 0xaa
\c b equ 0xcc
\c c equ 0xf0
\c imm equ a | b & c
Here, values for "a", "b" and "c" together are all possible bit configurations
that a 3 input function can take ("a" being the least significant bit and "c"
being the most significant one). Then the "imm" variable is calculated by
evaluating the desired logic function, in this case "a or b and c", thereby
getting the function's output column that one would get when writing out the
truth tables.
Note that only the expression must be written using the bitwise
operators \c{&}, \c{|}, \c{^}, and \c{~}. Using the boolean operators
\c{&&}, \c{||}, \c{^^}, \c{!} and \c{? :} will not work correctly.
The \i\c{vtern} standard macro package, \k{pkg_vtern}, allows for
these kinds of expressions without introducing the symbols \c{a},
\c{b} and \c{c} into the global namespace:
\c %use vtern
\c vpternlogd xmm1, xmm2, xmm3, a | b & c
\c vpternlogq ymm4, ymm5, xmm6, (b ^ c) & ~a
\c ; a, b, and c are not defined as symbols elsewhere
\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_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.