   This file documents NASM, the Netwide Assembler: an assembler
targetting the Intel x86 series of processors, with portable source.

   Copyright 2002 The NASM Development Team

   All rights reserved. This document is redistributable under the
licence given in the file "COPYING" distributed in the NASM archive.

B.2.5. Effective Address Encoding: ModR/M and SIB
-------------------------------------------------

   An effective address is encoded in up to three parts: a ModR/M byte,
an optional SIB byte, and an optional byte, word or doubleword
displacement field.

   The ModR/M byte consists of three fields: the `mod' field, ranging
from 0 to 3, in the upper two bits of the byte, the `r/m' field,
ranging from 0 to 7, in the lower three bits, and the spare (register)
field in the middle (bit 3 to bit 5). The spare field is not relevant to
the effective address being encoded, and either contains an extension to
the instruction opcode or the register value of another operand.

   The ModR/M system can be used to encode a direct register reference
rather than a memory access. This is always done by setting the `mod'
field to 3 and the `r/m' field to the register value of the register in
question (it must be a general-purpose register, and the size of the
register must already be implicit in the encoding of the rest of the
instruction). In this case, the SIB byte and displacement field are both
absent.

   In 16-bit addressing mode (either `BITS 16' with no `67' prefix, or
`BITS 32' with a `67' prefix), the SIB byte is never used. The general
rules for `mod' and `r/m' (there is an exception, given below) are:

   * The `mod' field gives the length of the displacement field: 0
     means no displacement, 1 means one byte, and 2 means two bytes.

   * The `r/m' field encodes the combination of registers to be added to
     the displacement to give the accessed address: 0 means `BX+SI', 1
     means `BX+DI', 2 means `BP+SI', 3 means `BP+DI', 4 means `SI'
     only, 5 means `DI' only, 6 means `BP' only, and 7 means `BX' only.

   However, there is a special case:

   * If `mod' is 0 and `r/m' is 6, the effective address encoded is not
     `[BP]' as the above rules would suggest, but instead `[disp16]':
     the displacement field is present and is two bytes long, and no
     registers are added to the displacement.

   Therefore the effective address `[BP]' cannot be encoded as
efficiently as `[BX]'; so if you code `[BP]' in a program, NASM adds a
notional 8-bit zero displacement, and sets `mod' to 1, `r/m' to 6, and
the one-byte displacement field to 0.

   In 32-bit addressing mode (either `BITS 16' with a `67' prefix, or
`BITS 32' with no `67' prefix) the general rules (again, there are
exceptions) for `mod' and `r/m' are:

   * The `mod' field gives the length of the displacement field: 0
     means no displacement, 1 means one byte, and 2 means four bytes.

   * If only one register is to be added to the displacement, and it is
     not `ESP', the `r/m' field gives its register value, and the SIB
     byte is absent. If the `r/m' field is 4 (which would encode `ESP'),
     the SIB byte is present and gives the combination and scaling of
     registers to be added to the displacement.

   If the SIB byte is present, it describes the combination of
registers (an optional base register, and an optional index register
scaled by multiplication by 1, 2, 4 or 8) to be added to the
displacement. The SIB byte is divided into the `scale' field, in the
top two bits, the `index' field in the next three, and the `base' field
in the bottom three. The general rules are:

   * The `base' field encodes the register value of the base register.

   * The `index' field encodes the register value of the index register,
     unless it is 4, in which case no index register is used (so `ESP'
     cannot be used as an index register).

   * The `scale' field encodes the multiplier by which the index
     register is scaled before adding it to the base and displacement:
     0 encodes a multiplier of 1, 1 encodes 2, 2 encodes 4 and 3
     encodes 8.

   The exceptions to the 32-bit encoding rules are:

   * If `mod' is 0 and `r/m' is 5, the effective address encoded is not
     `[EBP]' as the above rules would suggest, but instead `[disp32]':
     the displacement field is present and is four bytes long, and no
     registers are added to the displacement.

   * If `mod' is 0, `r/m' is 4 (meaning the SIB byte is present) and
     `base' is 4, the effective address encoded is not `[EBP+index]' as
     the above rules would suggest, but instead `[disp32+index]': the
     displacement field is present and is four bytes long, and there is
     no base register (but the index register is still processed in the
     normal way).

B.3. Key to Instruction Flags
=============================

   Given along with each instruction in this appendix is a set of flags,
denoting the type of the instruction. The types are as follows:

   * `8086', `186', `286', `386', `486', `PENT' and `P6' denote the
     lowest processor type that supports the instruction. Most
     instructions run on all processors above the given type; those
     that do not are documented. The Pentium II contains no additional
     instructions beyond the P6 (Pentium Pro); from the point of view
     of its instruction set, it can be thought of as a P6 with MMX
     capability.

   * `3DNOW' indicates that the instruction is a 3DNow! one, and will
     run on the AMD K6-2 and later processors. ATHLON extensions to the
     3DNow!  instruction set are documented as such.

   * `CYRIX' indicates that the instruction is specific to Cyrix
     processors, for example the extra MMX instructions in the Cyrix
     extended MMX instruction set.

   * `FPU' indicates that the instruction is a floating-point one, and
     will only run on machines with a coprocessor (automatically
     including 486DX, Pentium and above).

   * `KATMAI' indicates that the instruction was introduced as part of
     the Katmai New Instruction set. These instructions are available
     on the Pentium III and later processors. Those which are not
     specifically SSE instructions are also available on the AMD Athlon.

   * `MMX' indicates that the instruction is an MMX one, and will run on
     MMX-capable Pentium processors and the Pentium II.

   * `PRIV' indicates that the instruction is a protected-mode
     management instruction. Many of these may only be used in
     protected mode, or only at privilege level zero.

   * `SSE' and `SSE2' indicate that the instruction is a Streaming SIMD
     Extension instruction. These instructions operate on multiple
     values in a single operation. SSE was introduced with the Pentium
     III and SSE2 was introduced with the Pentium 4.

   * `UNDOC' indicates that the instruction is an undocumented one, and
     not part of the official Intel Architecture; it may or may not be
     supported on any given machine.

   * `WILLAMETTE' indicates that the instruction was introduced as part
     of the new instruction set in the Pentium 4 and Intel Xeon
     processors. These instructions are also known as SSE2 instructions.

B.4. x86 Instruction Set
========================

B.4.1. `AAA', `AAS', `AAM', `AAD': ASCII Adjustments
----------------------------------------------------

     AAA                           ; 37                   [8086]

     AAS                           ; 3F                   [8086]

     AAD                           ; D5 0A                [8086]
     AAD imm                       ; D5 ib                [8086]

     AAM                           ; D4 0A                [8086]
     AAM imm                       ; D4 ib                [8086]

   These instructions are used in conjunction with the add, subtract,
multiply and divide instructions to perform binary-coded decimal
arithmetic in _unpacked_ (one BCD digit per byte - easy to translate to
and from `ASCII', hence the instruction names) form. There are also
packed BCD instructions `DAA' and `DAS': see Section B.4.57.

   * `AAA' (ASCII Adjust After Addition) should be used after a one-byte
     `ADD' instruction whose destination was the `AL' register: by
     means of examining the value in the low nibble of `AL' and also the
     auxiliary carry flag `AF', it determines whether the addition has
     overflowed, and adjusts it (and sets the carry flag) if so. You
     can add long BCD strings together by doing `ADD'/`AAA' on the low
     digits, then doing `ADC'/`AAA' on each subsequent digit.

   * `AAS' (ASCII Adjust AL After Subtraction) works similarly to
     `AAA', but is for use after `SUB' instructions rather than `ADD'.

   * `AAM' (ASCII Adjust AX After Multiply) is for use after you have
     multiplied two decimal digits together and left the result in
     `AL': it divides `AL' by ten and stores the quotient in `AH',
     leaving the remainder in `AL'. The divisor 10 can be changed by
     specifying an operand to the instruction: a particularly handy use
     of this is `AAM 16', causing the two nibbles in `AL' to be
     separated into `AH' and `AL'.

   * `AAD' (ASCII Adjust AX Before Division) performs the inverse
     operation to `AAM': it multiplies `AH' by ten, adds it to `AL', and
     sets `AH' to zero. Again, the multiplier 10 can be changed.

B.4.2. `ADC': Add with Carry
----------------------------

     ADC r/m8,reg8                 ; 10 /r                [8086]
     ADC r/m16,reg16               ; o16 11 /r            [8086]
     ADC r/m32,reg32               ; o32 11 /r            [386]

     ADC reg8,r/m8                 ; 12 /r                [8086]
     ADC reg16,r/m16               ; o16 13 /r            [8086]
     ADC reg32,r/m32               ; o32 13 /r            [386]

     ADC r/m8,imm8                 ; 80 /2 ib             [8086]
     ADC r/m16,imm16               ; o16 81 /2 iw         [8086]
     ADC r/m32,imm32               ; o32 81 /2 id         [386]

     ADC r/m16,imm8                ; o16 83 /2 ib         [8086]
     ADC r/m32,imm8                ; o32 83 /2 ib         [386]

     ADC AL,imm8                   ; 14 ib                [8086]
     ADC AX,imm16                  ; o16 15 iw            [8086]
     ADC EAX,imm32                 ; o32 15 id            [386]

   `ADC' performs integer addition: it adds its two operands together,
plus the value of the carry flag, and leaves the result in its
destination (first) operand. The destination operand can be a register
or a memory location. The source operand can be a register, a memory
location or an immediate value.

   The flags are set according to the result of the operation: in
particular, the carry flag is affected and can be used by a subsequent
`ADC' instruction.

   In the forms with an 8-bit immediate second operand and a longer
first operand, the second operand is considered to be signed, and is
sign- extended to the length of the first operand. In these cases, the
`BYTE' qualifier is necessary to force NASM to generate this form of
the instruction.

   To add two numbers without also adding the contents of the carry
flag, use `ADD' (see Section B.4.3).

B.4.3. `ADD': Add Integers
--------------------------

     ADD r/m8,reg8                 ; 00 /r                [8086]
     ADD r/m16,reg16               ; o16 01 /r            [8086]
     ADD r/m32,reg32               ; o32 01 /r            [386]

     ADD reg8,r/m8                 ; 02 /r                [8086]
     ADD reg16,r/m16               ; o16 03 /r            [8086]
     ADD reg32,r/m32               ; o32 03 /r            [386]

     ADD r/m8,imm8                 ; 80 /0 ib             [8086]
     ADD r/m16,imm16               ; o16 81 /0 iw         [8086]
     ADD r/m32,imm32               ; o32 81 /0 id         [386]

     ADD r/m16,imm8                ; o16 83 /0 ib         [8086]
     ADD r/m32,imm8                ; o32 83 /0 ib         [386]

     ADD AL,imm8                   ; 04 ib                [8086]
     ADD AX,imm16                  ; o16 05 iw            [8086]
     ADD EAX,imm32                 ; o32 05 id            [386]

   `ADD' performs integer addition: it adds its two operands together,
and leaves the result in its destination (first) operand. The
destination operand can be a register or a memory location. The source
operand can be a register, a memory location or an immediate value.

   The flags are set according to the result of the operation: in
particular, the carry flag is affected and can be used by a subsequent
`ADC' instruction.

   In the forms with an 8-bit immediate second operand and a longer
first operand, the second operand is considered to be signed, and is
sign- extended to the length of the first operand. In these cases, the
`BYTE' qualifier is necessary to force NASM to generate this form of
the instruction.

B.4.4. `ADDPD': ADD Packed Double-Precision FP Values
-----------------------------------------------------

     ADDPD xmm1,xmm2/mem128        ; 66 0F 58 /r     [WILLAMETTE,SSE2]

   `ADDPD' performs addition on each of two packed double-precision FP
value pairs.

        dst[0-63]   := dst[0-63]   + src[0-63],
        dst[64-127] := dst[64-127] + src[64-127].

   The destination is an `XMM' register. The source operand can be
either an `XMM' register or a 128-bit memory location.

B.4.5. `ADDPS': ADD Packed Single-Precision FP Values
-----------------------------------------------------

     ADDPS xmm1,xmm2/mem128        ; 0F 58 /r        [KATMAI,SSE]

   `ADDPS' performs addition on each of four packed single-precision FP
value pairs

        dst[0-31]   := dst[0-31]   + src[0-31],
        dst[32-63]  := dst[32-63]  + src[32-63],
        dst[64-95]  := dst[64-95]  + src[64-95],
        dst[96-127] := dst[96-127] + src[96-127].

   The destination is an `XMM' register. The source operand can be
either an `XMM' register or a 128-bit memory location.

B.4.6. `ADDSD': ADD Scalar Double-Precision FP Values
-----------------------------------------------------

     ADDSD xmm1,xmm2/mem64         ; F2 0F 58 /r     [KATMAI,SSE]

   `ADDSD' adds the low double-precision FP values from the source and
destination operands and stores the double-precision FP result in the
destination operand.

        dst[0-63]   := dst[0-63] + src[0-63],
        dst[64-127) remains unchanged.

   The destination is an `XMM' register. The source operand can be
either an `XMM' register or a 64-bit memory location.

B.4.7. `ADDSS': ADD Scalar Single-Precision FP Values
-----------------------------------------------------

     ADDSS xmm1,xmm2/mem32         ; F3 0F 58 /r     [WILLAMETTE,SSE2]

   `ADDSS' adds the low single-precision FP values from the source and
destination operands and stores the single-precision FP result in the
destination operand.

        dst[0-31]   := dst[0-31] + src[0-31],
        dst[32-127] remains unchanged.

   The destination is an `XMM' register. The source operand can be
either an `XMM' register or a 32-bit memory location.

B.4.8. `AND': Bitwise AND
-------------------------

     AND r/m8,reg8                 ; 20 /r                [8086]
     AND r/m16,reg16               ; o16 21 /r            [8086]
     AND r/m32,reg32               ; o32 21 /r            [386]

     AND reg8,r/m8                 ; 22 /r                [8086]
     AND reg16,r/m16               ; o16 23 /r            [8086]
     AND reg32,r/m32               ; o32 23 /r            [386]

     AND r/m8,imm8                 ; 80 /4 ib             [8086]
     AND r/m16,imm16               ; o16 81 /4 iw         [8086]
     AND r/m32,imm32               ; o32 81 /4 id         [386]

     AND r/m16,imm8                ; o16 83 /4 ib         [8086]
     AND r/m32,imm8                ; o32 83 /4 ib         [386]

     AND AL,imm8                   ; 24 ib                [8086]
     AND AX,imm16                  ; o16 25 iw            [8086]
     AND EAX,imm32                 ; o32 25 id            [386]

   `AND' performs a bitwise AND operation between its two operands (i.e.
each bit of the result is 1 if and only if the corresponding bits of the
two inputs were both 1), and stores the result in the destination
(first) operand. The destination operand can be a register or a memory
location.  The source operand can be a register, a memory location or
an immediate value.

   In the forms with an 8-bit immediate second operand and a longer
first operand, the second operand is considered to be signed, and is
sign- extended to the length of the first operand. In these cases, the
`BYTE' qualifier is necessary to force NASM to generate this form of
the instruction.

   The `MMX' instruction `PAND' (see Section B.4.202) performs
the same operation on the 64-bit `MMX' registers.

B.4.9. `ANDNPD': Bitwise Logical AND NOT of Packed Double-Precision FP Values
-----------------------------------------------------------------------------

     ANDNPD xmm1,xmm2/mem128       ; 66 0F 55 /r     [WILLAMETTE,SSE2]

   `ANDNPD' inverts the bits of the two double-precision floating-point
values in the destination register, and then performs a logical AND
between the two double-precision floating-point values in the source
operand and the temporary inverted result, storing the result in the
destination register.

        dst[0-63]   := src[0-63]   AND NOT dst[0-63],
        dst[64-127] := src[64-127] AND NOT dst[64-127].

   The destination is an `XMM' register. The source operand can be
either an `XMM' register or a 128-bit memory location.

B.4.10. `ANDNPS': Bitwise Logical AND NOT of Packed Single-Precision FP Values
------------------------------------------------------------------------------

     ANDNPS xmm1,xmm2/mem128       ; 0F 55 /r        [KATMAI,SSE]

   `ANDNPS' inverts the bits of the four single-precision floating-point
values in the destination register, and then performs a logical AND
between the four single-precision floating-point values in the source
operand and the temporary inverted result, storing the result in the
destination register.

        dst[0-31]   := src[0-31]   AND NOT dst[0-31],
        dst[32-63]  := src[32-63]  AND NOT dst[32-63],
        dst[64-95]  := src[64-95]  AND NOT dst[64-95],
        dst[96-127] := src[96-127] AND NOT dst[96-127].

   The destination is an `XMM' register. The source operand can be
either an `XMM' register or a 128-bit memory location.

B.4.11. `ANDPD': Bitwise Logical AND For Single FP
--------------------------------------------------

     ANDPD xmm1,xmm2/mem128        ; 66 0F 54 /r     [WILLAMETTE,SSE2]

   `ANDPD' performs a bitwise logical AND of the two double-precision
floating point values in the source and destination operand, and stores
the result in the destination register.

        dst[0-63]   := src[0-63]   AND dst[0-63],
        dst[64-127] := src[64-127] AND dst[64-127].

   The destination is an `XMM' register. The source operand can be
either an `XMM' register or a 128-bit memory location.

B.4.12. `ANDPS': Bitwise Logical AND For Single FP
--------------------------------------------------

     ANDPS xmm1,xmm2/mem128        ; 0F 54 /r        [KATMAI,SSE]

   `ANDPS' performs a bitwise logical AND of the four single-precision
floating point values in the source and destination operand, and stores
the result in the destination register.

        dst[0-31]   := src[0-31]   AND dst[0-31],
        dst[32-63]  := src[32-63]  AND dst[32-63],
        dst[64-95]  := src[64-95]  AND dst[64-95],
        dst[96-127] := src[96-127] AND dst[96-127].

   The destination is an `XMM' register. The source operand can be
either an `XMM' register or a 128-bit memory location.

B.4.13. `ARPL': Adjust RPL Field of Selector
--------------------------------------------

     ARPL r/m16,reg16              ; 63 /r                [286,PRIV]

   `ARPL' expects its two word operands to be segment selectors. It
adjusts the `RPL' (requested privilege level - stored in the bottom two
bits of the selector) field of the destination (first) operand to
ensure that it is no less (i.e. no more privileged than) the `RPL'
field of the source operand. The zero flag is set if and only if a
change had to be made.

B.4.14. `BOUND': Check Array Index against Bounds
-------------------------------------------------

     BOUND reg16,mem               ; o16 62 /r            [186]
     BOUND reg32,mem               ; o32 62 /r            [386]

   `BOUND' expects its second operand to point to an area of memory
containing two signed values of the same size as its first operand (i.e.
two words for the 16-bit form; two doublewords for the 32-bit form). It
performs two signed comparisons: if the value in the register passed as
its first operand is less than the first of the in-memory values, or is
greater than or equal to the second, it throws a `BR' exception.
Otherwise, it does nothing.

B.4.15. `BSF', `BSR': Bit Scan
------------------------------

     BSF reg16,r/m16               ; o16 0F BC /r         [386]
     BSF reg32,r/m32               ; o32 0F BC /r         [386]

     BSR reg16,r/m16               ; o16 0F BD /r         [386]
     BSR reg32,r/m32               ; o32 0F BD /r         [386]

   * `BSF' searches for the least significant set bit in its source
     (second) operand, and if it finds one, stores the index in its
     destination (first) operand. If no set bit is found, the contents
     of the destination operand are undefined. If the source operand is
     zero, the zero flag is set.

   * `BSR' performs the same function, but searches from the top
     instead, so it finds the most significant set bit.

   Bit indices are from 0 (least significant) to 15 or 31 (most
significant).  The destination operand can only be a register. The
source operand can be a register or a memory location.

B.4.16. `BSWAP': Byte Swap
--------------------------

     BSWAP reg32                   ; o32 0F C8+r          [486]

   `BSWAP' swaps the order of the four bytes of a 32-bit register: bits
0-7 exchange places with bits 24-31, and bits 8-15 swap with bits 16-23.
There is no explicit 16-bit equivalent: to byte-swap `AX', `BX', `CX'
or `DX', `XCHG' can be used. When `BSWAP' is used with a 16-bit
register, the result is undefined.

B.4.17. `BT', `BTC', `BTR', `BTS': Bit Test
-------------------------------------------

     BT r/m16,reg16                ; o16 0F A3 /r         [386]
     BT r/m32,reg32                ; o32 0F A3 /r         [386]
     BT r/m16,imm8                 ; o16 0F BA /4 ib      [386]
     BT r/m32,imm8                 ; o32 0F BA /4 ib      [386]

     BTC r/m16,reg16               ; o16 0F BB /r         [386]
     BTC r/m32,reg32               ; o32 0F BB /r         [386]
     BTC r/m16,imm8                ; o16 0F BA /7 ib      [386]
     BTC r/m32,imm8                ; o32 0F BA /7 ib      [386]

     BTR r/m16,reg16               ; o16 0F B3 /r         [386]
     BTR r/m32,reg32               ; o32 0F B3 /r         [386]
     BTR r/m16,imm8                ; o16 0F BA /6 ib      [386]
     BTR r/m32,imm8                ; o32 0F BA /6 ib      [386]

     BTS r/m16,reg16               ; o16 0F AB /r         [386]
     BTS r/m32,reg32               ; o32 0F AB /r         [386]
     BTS r/m16,imm                 ; o16 0F BA /5 ib      [386]
     BTS r/m32,imm                 ; o32 0F BA /5 ib      [386]

   These instructions all test one bit of their first operand, whose
index is given by the second operand, and store the value of that bit
into the carry flag. Bit indices are from 0 (least significant) to 15
or 31 (most significant).

   In addition to storing the original value of the bit into the carry
flag, `BTR' also resets (clears) the bit in the operand itself. `BTS'
sets the bit, and `BTC' complements the bit. `BT' does not modify its
operands.

   The destination can be a register or a memory location. The source
can be a register or an immediate value.

   If the destination operand is a register, the bit offset should be
in the range 0-15 (for 16-bit operands) or 0-31 (for 32-bit operands).
An immediate value outside these ranges will be taken modulo 16/32 by
the processor.

   If the destination operand is a memory location, then an immediate
bit offset follows the same rules as for a register. If the bit offset
is in a register, then it can be anything within the signed range of
the register used (ie, for a 32-bit operand, it can be (-2^31) to (2^31
- 1)