   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.4.125. `INVD': Invalidate Internal Caches
-------------------------------------------

     INVD                          ; 0F 08                [486]

   `INVD' invalidates and empties the processor's internal caches, and
causes the processor to instruct external caches to do the same. It does
not write the contents of the caches back to memory first: any modified
data held in the caches will be lost. To write the data back first, use
`WBINVD' (see Section B.4.328).

B.4.126. `INVLPG': Invalidate TLB Entry
---------------------------------------

     INVLPG mem                    ; 0F 01 /7             [486]

   `INVLPG' invalidates the translation lookahead buffer (TLB) entry
associated with the supplied memory address.

B.4.127. `IRET', `IRETW', `IRETD': Return from Interrupt
--------------------------------------------------------

     IRET                          ; CF                   [8086]
     IRETW                         ; o16 CF               [8086]
     IRETD                         ; o32 CF               [386]

   `IRET' returns from an interrupt (hardware or software) by means of
popping `IP' (or `EIP'), `CS' and the flags off the stack and then
continuing execution from the new `CS:IP'.

   `IRETW' pops `IP', `CS' and the flags as 2 bytes each, taking 6
bytes off the stack in total. `IRETD' pops `EIP' as 4 bytes, pops a
further 4 bytes of which the top two are discarded and the bottom two
go into `CS', and pops the flags as 4 bytes as well, taking 12 bytes
off the stack.

   `IRET' is a shorthand for either `IRETW' or `IRETD', depending on
the default `BITS' setting at the time.

B.4.128. `Jcc': Conditional Branch
----------------------------------

     Jcc imm                       ; 70+cc rb             [8086]
     Jcc NEAR imm                  ; 0F 80+cc rw/rd       [386]

   The conditional jump instructions execute a near (same segment) jump
if and only if their conditions are satisfied. For example, `JNZ' jumps
only if the zero flag is not set.

   The ordinary form of the instructions has only a 128-byte range; the
`NEAR' form is a 386 extension to the instruction set, and can span the
full size of a segment. NASM will not override your choice of jump
instruction: if you want `Jcc NEAR', you have to use the `NEAR' keyword.

   The `SHORT' keyword is allowed on the first form of the instruction,
for clarity, but is not necessary.

   For details of the condition codes, see Section B.2.2.

B.4.129. `JCXZ', `JECXZ': Jump if CX/ECX Zero
---------------------------------------------

     JCXZ imm                      ; a16 E3 rb            [8086]
     JECXZ imm                     ; a32 E3 rb            [386]

   `JCXZ' performs a short jump (with maximum range 128 bytes) if and
only if the contents of the `CX' register is 0. `JECXZ' does the same
thing, but with `ECX'.

B.4.130. `JMP': Jump
--------------------

     JMP imm                       ; E9 rw/rd             [8086]
     JMP SHORT imm                 ; EB rb                [8086]
     JMP imm:imm16                 ; o16 EA iw iw         [8086]
     JMP imm:imm32                 ; o32 EA id iw         [386]
     JMP FAR mem                   ; o16 FF /5            [8086]
     JMP FAR mem32                 ; o32 FF /5            [386]
     JMP r/m16                     ; o16 FF /4            [8086]
     JMP r/m32                     ; o32 FF /4            [386]

   `JMP' jumps to a given address. The address may be specified as an
absolute segment and offset, or as a relative jump within the current
segment.

   `JMP SHORT imm' has a maximum range of 128 bytes, since the
displacement is specified as only 8 bits, but takes up less code space.
NASM does not choose when to generate `JMP SHORT' for you: you must
explicitly code `SHORT' every time you want a short jump.

   You can choose between the two immediate far jump forms (`JMP
imm:imm') by the use of the `WORD' and `DWORD' keywords: `JMP WORD
0x1234:0x5678') or `JMP DWORD 0x1234:0x56789abc'.

   The `JMP FAR mem' forms execute a far jump by loading the destination
address out of memory. The address loaded consists of 16 or 32 bits of
offset (depending on the operand size), and 16 bits of segment. The
operand size may be overridden using `JMP WORD FAR mem' or `JMP DWORD
FAR mem'.

   The `JMP r/m' forms execute a near jump (within the same segment),
loading the destination address out of memory or out of a register. The
keyword `NEAR' may be specified, for clarity, in these forms, but is
not necessary. Again, operand size can be overridden using `JMP WORD
mem' or `JMP DWORD mem'.

   As a convenience, NASM does not require you to jump to a far symbol
by coding the cumbersome `JMP SEG routine:routine', but instead allows
the easier synonym `JMP FAR routine'.

   The `CALL r/m' forms given above are near calls; NASM will accept the
`NEAR' keyword (e.g. `CALL NEAR [address]'), even though it is not
strictly necessary.

B.4.131. `LAHF': Load AH from Flags
-----------------------------------

     LAHF                          ; 9F                   [8086]

   `LAHF' sets the `AH' register according to the contents of the low
byte of the flags word.

   The operation of `LAHF' is:

      AH <-- SF:ZF:0:AF:0:PF:1:CF

   See also `SAHF' (see Section B.4.282).

B.4.132. `LAR': Load Access Rights
----------------------------------

     LAR reg16,r/m16               ; o16 0F 02 /r         [286,PRIV]
     LAR reg32,r/m32               ; o32 0F 02 /r         [286,PRIV]

   `LAR' takes the segment selector specified by its source (second)
operand, finds the corresponding segment descriptor in the GDT or LDT,
and loads the access-rights byte of the descriptor into its destination
(first) operand.

B.4.133. `LDMXCSR': Load Streaming SIMD Extension Control/Status
----------------------------------------------------------------

     LDMXCSR mem32                 ; 0F AE /2        [KATMAI,SSE]

   `LDMXCSR' loads 32-bits of data from the specified memory location
into the `MXCSR' control/status register. `MXCSR' is used to enable
masked/unmasked exception handling, to set rounding modes, to set
flush-to-zero mode, and to view exception status flags.

   For details of the `MXCSR' register, see the Intel processor docs.

   See also `STMXCSR' (see Section B.4.302

B.4.134. `LDS', `LES', `LFS', `LGS', `LSS': Load Far Pointer
------------------------------------------------------------

     LDS reg16,mem                 ; o16 C5 /r            [8086]
     LDS reg32,mem                 ; o32 C5 /r            [386]

     LES reg16,mem                 ; o16 C4 /r            [8086]
     LES reg32,mem                 ; o32 C4 /r            [386]

     LFS reg16,mem                 ; o16 0F B4 /r         [386]
     LFS reg32,mem                 ; o32 0F B4 /r         [386]

     LGS reg16,mem                 ; o16 0F B5 /r         [386]
     LGS reg32,mem                 ; o32 0F B5 /r         [386]

     LSS reg16,mem                 ; o16 0F B2 /r         [386]
     LSS reg32,mem                 ; o32 0F B2 /r         [386]

   These instructions load an entire far pointer (16 or 32 bits of
offset, plus 16 bits of segment) out of memory in one go. `LDS', for
example, loads 16 or 32 bits from the given memory address into the
given register (depending on the size of the register), then loads the
_next_ 16 bits from memory into `DS'. `LES', `LFS', `LGS' and `LSS'
work in the same way but use the other segment registers.

B.4.135. `LEA': Load Effective Address
--------------------------------------

     LEA reg16,mem                 ; o16 8D /r            [8086]
     LEA reg32,mem                 ; o32 8D /r            [386]

   `LEA', despite its syntax, does not access memory. It calculates the
effective address specified by its second operand as if it were going to
load or store data from it, but instead it stores the calculated address
into the register specified by its first operand. This can be used to
perform quite complex calculations (e.g. `LEA EAX,[EBX+ECX*4+100]') in
one instruction.

   `LEA', despite being a purely arithmetic instruction which accesses
no memory, still requires square brackets around its second operand, as
if it were a memory reference.

   The size of the calculation is the current _address_ size, and the
size that the result is stored as is the current _operand_ size. If the
address and operand size are not the same, then if the addressing mode
was 32-bits, the low 16-bits are stored, and if the address was
16-bits, it is zero-extended to 32-bits before storing.

B.4.136. `LEAVE': Destroy Stack Frame
-------------------------------------

     LEAVE                         ; C9                   [186]

   `LEAVE' destroys a stack frame of the form created by the `ENTER'
instruction (see Section B.4.65). It is functionally equivalent
to `MOV ESP,EBP' followed by `POP EBP' (or `MOV SP,BP' followed by `POP
BP' in 16-bit mode).

B.4.137. `LFENCE': Load Fence
-----------------------------

     LFENCE                        ; 0F AE /5        [WILLAMETTE,SSE2]

   `LFENCE' performs a serialising operation on all loads from memory
that were issued before the `LFENCE' instruction. This guarantees that
all memory reads before the `LFENCE' instruction are visible before any
reads after the `LFENCE' instruction.

   `LFENCE' is ordered respective to other `LFENCE' instruction,
`MFENCE', any memory read and any other serialising instruction (such
as `CPUID').

   Weakly ordered memory types can be used to achieve higher processor
performance through such techniques as out-of-order issue and
speculative reads. The degree to which a consumer of data recognizes or
knows that the data is weakly ordered varies among applications and may
be unknown to the producer of this data. The `LFENCE' instruction
provides a performance-efficient way of ensuring load ordering between
routines that produce weakly-ordered results and routines that consume
that data.

   `LFENCE' uses the following ModRM encoding:

               Mod (7:6)        = 11B
               Reg/Opcode (5:3) = 101B
               R/M (2:0)        = 000B

   All other ModRM encodings are defined to be reserved, and use of
these encodings risks incompatibility with future processors.

   See also `SFENCE' (see Section B.4.288) and `MFENCE' (see
Section B.4.151).

B.4.138. `LGDT', `LIDT', `LLDT': Load Descriptor Tables
-------------------------------------------------------

     LGDT mem                      ; 0F 01 /2             [286,PRIV]
     LIDT mem                      ; 0F 01 /3             [286,PRIV]
     LLDT r/m16                    ; 0F 00 /2             [286,PRIV]

   `LGDT' and `LIDT' both take a 6-byte memory area as an operand: they
load a 32-bit linear address and a 16-bit size limit from that area (in
the opposite order) into the `GDTR' (global descriptor table register)
or `IDTR' (interrupt descriptor table register). These are the only
instructions which directly use _linear_ addresses, rather than
segment/offset pairs.

   `LLDT' takes a segment selector as an operand. The processor looks up
that selector in the GDT and stores the limit and base address given
there into the `LDTR' (local descriptor table register).

   See also `SGDT', `SIDT' and `SLDT' (see Section B.4.289).

B.4.139. `LMSW': Load/Store Machine Status Word
-----------------------------------------------

     LMSW r/m16                    ; 0F 01 /6             [286,PRIV]

   `LMSW' loads the bottom four bits of the source operand into the
bottom four bits of the `CR0' control register (or the Machine Status
Word, on 286 processors). See also `SMSW' (see Section B.4.296).

B.4.140. `LOADALL', `LOADALL286': Load Processor State
------------------------------------------------------

     LOADALL                       ; 0F 07                [386,UNDOC]
     LOADALL286                    ; 0F 05                [286,UNDOC]

   This instruction, in its two different-opcode forms, is apparently
supported on most 286 processors, some 386 and possibly some 486. The
opcode differs between the 286 and the 386.

   The function of the instruction is to load all information relating
to the state of the processor out of a block of memory: on the 286,
this block is located implicitly at absolute address `0x800', and on
the 386 and 486 it is at `[ES:EDI]'.

B.4.141. `LODSB', `LODSW', `LODSD': Load from String
----------------------------------------------------

     LODSB                         ; AC                   [8086]
     LODSW                         ; o16 AD               [8086]
     LODSD                         ; o32 AD               [386]

   `LODSB' loads a byte from `[DS:SI]' or `[DS:ESI]' into `AL'. It then
increments or decrements (depending on the direction flag: increments
if the flag is clear, decrements if it is set) `SI' or `ESI'.

   The register used is `SI' if the address size is 16 bits, and `ESI'
if it is 32 bits. If you need to use an address size not equal to the
current `BITS' setting, you can use an explicit `a16' or `a32' prefix.

   The segment register used to load from `[SI]' or `[ESI]' can be
overridden by using a segment register name as a prefix (for example,
`ES LODSB').

   `LODSW' and `LODSD' work in the same way, but they load a word or a
doubleword instead of a byte, and increment or decrement the addressing
registers by 2 or 4 instead of 1.

B.4.142. `LOOP', `LOOPE', `LOOPZ', `LOOPNE', `LOOPNZ': Loop with Counter
------------------------------------------------------------------------

     LOOP imm                      ; E2 rb                [8086]
     LOOP imm,CX                   ; a16 E2 rb            [8086]
     LOOP imm,ECX                  ; a32 E2 rb            [386]

     LOOPE imm                     ; E1 rb                [8086]
     LOOPE imm,CX                  ; a16 E1 rb            [8086]
     LOOPE imm,ECX                 ; a32 E1 rb            [386]
     LOOPZ imm                     ; E1 rb                [8086]
     LOOPZ imm,CX                  ; a16 E1 rb            [8086]
     LOOPZ imm,ECX                 ; a32 E1 rb            [386]

     LOOPNE imm                    ; E0 rb                [8086]
     LOOPNE imm,CX                 ; a16 E0 rb            [8086]
     LOOPNE imm,ECX                ; a32 E0 rb            [386]
     LOOPNZ imm                    ; E0 rb                [8086]
     LOOPNZ imm,CX                 ; a16 E0 rb            [8086]
     LOOPNZ imm,ECX                ; a32 E0 rb            [386]

   `LOOP' decrements its counter register (either `CX' or `ECX' - if
one is not specified explicitly, the `BITS' setting dictates which is
used) by one, and if the counter does not become zero as a result of
this operation, it jumps to the given label. The jump has a range of 128
bytes.

   `LOOPE' (or its synonym `LOOPZ') adds the additional condition that
it only jumps if the counter is nonzero _and_ the zero flag is set.
Similarly, `LOOPNE' (and `LOOPNZ') jumps only if the counter is nonzero
and the zero flag is clear.

B.4.143. `LSL': Load Segment Limit
----------------------------------

     LSL reg16,r/m16               ; o16 0F 03 /r         [286,PRIV]
     LSL reg32,r/m32               ; o32 0F 03 /r         [286,PRIV]

   `LSL' is given a segment selector in its source (second) operand; it
computes the segment limit value by loading the segment limit field from
the associated segment descriptor in the `GDT' or `LDT'. (This involves
shifting left by 12 bits if the segment limit is page-granular, and not
if it is byte-granular; so you end up with a byte limit in either
case.) The segment limit obtained is then loaded into the destination
(first) operand.

B.4.144. `LTR': Load Task Register
----------------------------------

     LTR r/m16                     ; 0F 00 /3             [286,PRIV]

   `LTR' looks up the segment base and limit in the GDT or LDT
descriptor specified by the segment selector given as its operand, and
loads them into the Task Register.

B.4.145. `MASKMOVDQU': Byte Mask Write
--------------------------------------

     MASKMOVDQU xmm1,xmm2          ; 66 0F F7 /r     [WILLAMETTE,SSE2]

   `MASKMOVDQU' stores data from xmm1 to the location specified by
`ES:(E)DI'. The size of the store depends on the address-size
attribute. The most significant bit in each byte of the mask register
xmm2 is used to selectively write the data (0 = no write, 1 = write) on
a per- byte basis.

B.4.146. `MASKMOVQ': Byte Mask Write
------------------------------------

     MASKMOVQ mm1,mm2              ; 0F F7 /r        [KATMAI,MMX]

   `MASKMOVQ' stores data from mm1 to the location specified by
`ES:(E)DI'. The size of the store depends on the address-size
attribute. The most significant bit in each byte of the mask register
mm2 is used to selectively write the data (0 = no write, 1 = write) on
a per- byte basis.

B.4.147. `MAXPD': Return Packed Double-Precision FP Maximum
-----------------------------------------------------------

     MAXPD xmm1,xmm2/m128          ; 66 0F 5F /r     [WILLAMETTE,SSE2]

   `MAXPD' performs a SIMD compare of the packed double-precision FP
numbers from xmm1 and xmm2/mem, and stores the maximum values of each
pair of values in xmm1. If the values being compared are both zeroes,
source2 (xmm2/m128) would be returned. If source2 (xmm2/m128) is an
SNaN, this SNaN is forwarded unchanged to the destination (i.e., a QNaN
version of the SNaN is not returned).

B.4.148. `MAXPS': Return Packed Single-Precision FP Maximum
-----------------------------------------------------------

     MAXPS xmm1,xmm2/m128          ; 0F 5F /r        [KATMAI,SSE]

   `MAXPS' performs a SIMD compare of the packed single-precision FP
numbers from xmm1 and xmm2/mem, and stores the maximum values of each
pair of values in xmm1. If the values being compared are both zeroes,
source2 (xmm2/m128) would be returned. If source2 (xmm2/m128) is an
SNaN, this SNaN is forwarded unchanged to the destination (i.e., a QNaN
version of the SNaN is not returned).

B.4.149. `MAXSD': Return Scalar Double-Precision FP Maximum
-----------------------------------------------------------

     MAXSD xmm1,xmm2/m64           ; F2 0F 5F /r     [WILLAMETTE,SSE2]

   `MAXSD' compares the low-order double-precision FP numbers from xmm1
and xmm2/mem, and stores the maximum value in xmm1. If the values being
compared are both zeroes, source2 (xmm2/m64) would be returned. If
source2 (xmm2/m64) is an SNaN, this SNaN is forwarded unchanged to the
destination (i.e., a QNaN version of the SNaN is not returned). The
high quadword of the destination is left unchanged.

B.4.150. `MAXSS': Return Scalar Single-Precision FP Maximum
-----------------------------------------------------------

     MAXSS xmm1,xmm2/m32           ; F3 0F 5F /r     [KATMAI,SSE]

   `MAXSS' compares the low-order single-precision FP numbers from xmm1
and xmm2/mem, and stores the maximum value in xmm1. If the values being
compared are both zeroes, source2 (xmm2/m32) would be returned. If
source2 (xmm2/m32) is an SNaN, this SNaN is forwarded unchanged to the
destination (i.e., a QNaN version of the SNaN is not returned). The
high three doublewords of the destination are left unchanged.

B.4.151. `MFENCE': Memory Fence
-------------------------------

     MFENCE                        ; 0F AE /6        [WILLAMETTE,SSE2]

   `MFENCE' performs a serialising operation on all loads from memory
and writes to memory that were issued before the `MFENCE' instruction.
This guarantees that all memory reads and writes before the `MFENCE'
instruction are completed before any reads and writes after the
`MFENCE' instruction.

   `MFENCE' is ordered respective to other `MFENCE' instructions,
`LFENCE', `SFENCE', any memory read and any other serialising
instruction (such as `CPUID').

   Weakly ordered memory types can be used to achieve higher processor
performance through such techniques as out-of-order issue, speculative
reads, write-combining, and write-collapsing. The degree to which a
consumer of data recognizes or knows that the data is weakly ordered
varies among applications and may be unknown to the producer of this
data. The `MFENCE' instruction provides a performance-efficient way of
ensuring load and store ordering between routines that produce
weakly-ordered results and routines that consume that data.

   `MFENCE' uses the following ModRM encoding:

               Mod (7:6)        = 11B
               Reg/Opcode (5:3) = 110B
               R/M (2:0)        = 000B

   All other ModRM encodings are defined to be reserved, and use of
these encodings risks incompatibility with future processors.

   See also `LFENCE' (see Section B.4.137) and `SFENCE' (see
Section B.4.288).

B.4.152. `MINPD': Return Packed Double-Precision FP Minimum
-----------------------------------------------------------

     MINPD xmm1,xmm2/m128          ; 66 0F 5D /r     [WILLAMETTE,SSE2]

   `MINPD' performs a SIMD compare of the packed double-precision FP
numbers from xmm1 and xmm2/mem, and stores the minimum values of each
pair of values in xmm1. If the values being compared are both zeroes,
source2 (xmm2/m128) would be returned. If source2 (xmm2/m128) is an
SNaN, this SNaN is forwarded unchanged to the destination (i.e., a QNaN
version of the SNaN is not returned).

B.4.153. `MINPS': Return Packed Single-Precision FP Minimum
-----------------------------------------------------------

     MINPS xmm1,xmm2/m128          ; 0F 5D /r        [KATMAI,SSE]

   `MINPS' performs a SIMD compare of the packed single-precision FP
numbers from xmm1 and xmm2/mem, and stores the minimum values of each
pair of values in xmm1. If the values being compared are both zeroes,
source2 (xmm2/m128) would be returned. If source2 (xmm2/m128) is an
SNaN, this SNaN is forwarded unchanged to the destination (i.e., a QNaN
version of the SNaN is not returned).

B.4.154. `MINSD': Return Scalar Double-Precision FP Minimum
-----------------------------------------------------------

     MINSD xmm1,xmm2/m64           ; F2 0F 5D /r     [WILLAMETTE,SSE2]

   `MINSD' compares the low-order double-precision FP numbers from xmm1
and xmm2/mem, and stores the minimum value in xmm1. If the values being
compared are both zeroes, source2 (xmm2/m64) would be returned. If
source2 (xmm2/m64) is an SNaN, this SNaN is forwarded unchanged to the
destination (i.e., a QNaN version of the SNaN is not returned). The
high quadword of the destination is left unchanged.

B.4.155. `MINSS': Return Scalar Single-Precision FP Minimum
-----------------------------------------------------------

     MINSS xmm1,xmm2/m32           ; F3 0F 5D /r     [KATMAI,SSE]

   `MINSS' compares the low-order single-precision FP numbers from xmm1
and xmm2/mem, and stores the minimum value in xmm1. If the values being
compared are both zeroes, source2 (xmm2/m32) would be returned. If
source2 (xmm2/m32) is an SNaN, this SNaN is forwarded unchanged to the
destination (i.e., a QNaN version of the SNaN is not returned). The
high three doublewords of the destination are left unchanged.

B.4.156. `MOV': Move Data
-------------------------

     MOV r/m8,reg8                 ; 88 /r                [8086]
     MOV r/m16,reg16               ; o16 89 /r            [8086]
     MOV r/m32,reg32               ; o32 89 /r            [386]
     MOV reg8,r/m8                 ; 8A /r                [8086]
     MOV reg16,r/m16               ; o16 8B /r            [8086]
     MOV reg32,r/m32               ; o32 8B /r            [386]

     MOV reg8,imm8                 ; B0+r ib              [8086]
     MOV reg16,imm16               ; o16 B8+r iw          [8086]
     MOV reg32,imm32               ; o32 B8+r id          [386]
     MOV r/m8,imm8                 ; C6 /0 ib             [8086]
     MOV r/m16,imm16               ; o16 C7 /0 iw         [8086]
     MOV r/m32,imm32               ; o32 C7 /0 id         [386]

     MOV AL,memoffs8               ; A0 ow/od             [8086]
     MOV AX,memoffs16              ; o16 A1 ow/od         [8086]
     MOV EAX,memoffs32             ; o32 A1 ow/od         [386]
     MOV memoffs8,AL               ; A2 ow/od             [8086]
     MOV memoffs16,AX              ; o16 A3 ow/od         [8086]
     MOV memoffs32,EAX             ; o32 A3 ow/od         [386]

     MOV r/m16,segreg              ; o16 8C /r            [8086]
     MOV r/m32,segreg              ; o32 8C /r            [386]
     MOV segreg,r/m16              ; o16 8E /r            [8086]
     MOV segreg,r/m32              ; o32 8E /r            [386]

     MOV reg32,CR0/2/3/4           ; 0F 20 /r             [386]
     MOV reg32,DR0/1/2/3/6/7       ; 0F 21 /r             [386]
     MOV reg32,TR3/4/5/6/7         ; 0F 24 /r             [386]
     MOV CR0/2/3/4,reg32           ; 0F 22 /r             [386]
     MOV DR0/1/2/3/6/7,reg32       ; 0F 23 /r             [386]
     MOV TR3/4/5/6/7,reg32         ; 0F 26 /r             [386]

   `MOV' copies the contents of its source (second) operand into its
destination (first) operand.

   In all forms of the `MOV' instruction, the two operands are the same
size, except for moving between a segment register and an `r/m32'
operand. These instructions are treated exactly like the corresponding
16- bit equivalent (so that, for example, `MOV DS,EAX' functions
identically to `MOV DS,AX' but saves a prefix when in 32-bit mode),
except that when a segment register is moved into a 32-bit destination,
the top two bytes of the result are undefined.

   `MOV' may not use `CS' as a destination.

   `CR4' is only a supported register on the Pentium and above.

   Test registers are supported on 386/486 processors and on some
non-Intel Pentium class processors.

B.4.157. `MOVAPD': Move Aligned Packed Double-Precision FP Values
-----------------------------------------------------------------

     MOVAPD xmm1,xmm2/mem128       ; 66 0F 28 /r     [WILLAMETTE,SSE2]
     MOVAPD xmm1/mem128,xmm2       ; 66 0F 29 /r     [WILLAMETTE,SSE2]

   `MOVAPD' moves a double quadword containing 2 packed double-precision
FP values from the source operand to the destination. When the source or
destination operand is a memory location, it must be aligned on a
16-byte boundary.

   To move data in and out of memory locations that are not known to be
on 16- byte boundaries, use the `MOVUPD' instruction (see Section B.4.182).

B.4.158. `MOVAPS': Move Aligned Packed Single-Precision FP Values
-----------------------------------------------------------------

     MOVAPS xmm1,xmm2/mem128       ; 0F 28 /r        [KATMAI,SSE]
     MOVAPS xmm1/mem128,xmm2       ; 0F 29 /r        [KATMAI,SSE]

   `MOVAPS' moves a double quadword containing 4 packed single-precision
FP values from the source operand to the destination. When the source or
destination operand is a memory location, it must be aligned on a
16-byte boundary.

   To move data in and out of memory locations that are not known to be
on 16- byte boundaries, use the `MOVUPS' instruction (see Section B.4.183).

B.4.159. `MOVD': Move Doubleword to/from MMX Register
-----------------------------------------------------

     MOVD mm,r/m32                 ; 0F 6E /r             [PENT,MMX]
     MOVD r/m32,mm                 ; 0F 7E /r             [PENT,MMX]
     MOVD xmm,r/m32                ; 66 0F 6E /r     [WILLAMETTE,SSE2]
     MOVD r/m32,xmm                ; 66 0F 7E /r     [WILLAMETTE,SSE2]

   `MOVD' copies 32 bits from its source (second) operand into its
destination (first) operand. When the destination is a 64-bit `MMX'
register or a 128-bit `XMM' register, the input value is zero-extended
to fill the destination register.

B.4.160. `MOVDQ2Q': Move Quadword from XMM to MMX register.
-----------------------------------------------------------

     MOVDQ2Q mm,xmm                ; F2 OF D6 /r     [WILLAMETTE,SSE2]

   `MOVDQ2Q' moves the low quadword from the source operand to the
destination operand.

B.4.161. `MOVDQA': Move Aligned Double Quadword
-----------------------------------------------

     MOVDQA xmm1,xmm2/m128         ; 66 OF 6F /r     [WILLAMETTE,SSE2]
     MOVDQA xmm1/m128,xmm2         ; 66 OF 7F /r     [WILLAMETTE,SSE2]

   `MOVDQA' moves a double quadword from the source operand to the
destination operand. When the source or destination operand is a memory
location, it must be aligned to a 16-byte boundary.

   To move a double quadword to or from unaligned memory locations, use
the `MOVDQU' instruction (see Section B.4.162).

B.4.162. `MOVDQU': Move Unaligned Double Quadword
-------------------------------------------------

     MOVDQU xmm1,xmm2/m128         ; F3 OF 6F /r     [WILLAMETTE,SSE2]
     MOVDQU xmm1/m128,xmm2         ; F3 OF 7F /r     [WILLAMETTE,SSE2]

   `MOVDQU' moves a double quadword from the source operand to the
destination operand. When the source or destination operand is a memory
location, the memory may be unaligned.

   To move a double quadword to or from known aligned memory locations,
use the `MOVDQA' instruction (see Section B.4.161).

B.4.163. `MOVHLPS': Move Packed Single-Precision FP High to Low
---------------------------------------------------------------

     MOVHLPS xmm1,xmm2             ; OF 12 /r        [KATMAI,SSE]

   `MOVHLPS' moves the two packed single-precision FP values from the
high quadword of the source register xmm2 to the low quadword of the
destination register, xmm2. The upper quadword of xmm1 is left
unchanged.

   The operation of this instruction is:

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

B.4.164. `MOVHPD': Move High Packed Double-Precision FP
-------------------------------------------------------

     MOVHPD xmm,m64               ; 66 OF 16 /r      [WILLAMETTE,SSE2]
     MOVHPD m64,xmm               ; 66 OF 17 /r      [WILLAMETTE,SSE2]

   `MOVHPD' moves a double-precision FP value between the source and
destination operands. One of the operands is a 64-bit memory location,
the other is the high quadword of an `XMM' register.

   The operation of this instruction is:

        mem[0-63]   := xmm[64-127];

   or

        xmm[0-63]   remains unchanged;
        xmm[64-127] := mem[0-63].

B.4.165. `MOVHPS': Move High Packed Single-Precision FP
-------------------------------------------------------

     MOVHPS xmm,m64               ; 0F 16 /r         [KATMAI,SSE]
     MOVHPS m64,xmm               ; 0F 17 /r         [KATMAI,SSE]

   `MOVHPS' moves two packed single-precision FP values between the
source and destination operands. One of the operands is a 64-bit memory
location, the other is the high quadword of an `XMM' register.

   The operation of this instruction is:

        mem[0-63]   := xmm[64-127];

   or

        xmm[0-63]   remains unchanged;
        xmm[64-127] := mem[0-63].

B.4.166. `MOVLHPS': Move Packed Single-Precision FP Low to High
---------------------------------------------------------------

     MOVLHPS xmm1,xmm2             ; OF 16 /r         [KATMAI,SSE]

   `MOVLHPS' moves the two packed single-precision FP values from the
low quadword of the source register xmm2 to the high quadword of the
destination register, xmm2. The low quadword of xmm1 is left unchanged.

   The operation of this instruction is:

        dst[0-63]   remains unchanged;
        dst[64-127] := src[0-63].

B.4.167. `MOVLPD': Move Low Packed Double-Precision FP
------------------------------------------------------

     MOVLPD xmm,m64                ; 66 OF 12 /r     [WILLAMETTE,SSE2]
     MOVLPD m64,xmm                ; 66 OF 13 /r     [WILLAMETTE,SSE2]

   `MOVLPD' moves a double-precision FP value between the source and
destination operands. One of the operands is a 64-bit memory location,
the other is the low quadword of an `XMM' register.

   The operation of this instruction is:

        mem(0-63)   := xmm(0-63);

   or

        xmm(0-63)   := mem(0-63);
        xmm(64-127) remains unchanged.

B.4.168. `MOVLPS': Move Low Packed Single-Precision FP
------------------------------------------------------

     MOVLPS xmm,m64                ; OF 12 /r        [KATMAI,SSE]
     MOVLPS m64,xmm                ; OF 13 /r        [KATMAI,SSE]

   `MOVLPS' moves two packed single-precision FP values between the
source and destination operands. One of the operands is a 64-bit memory
location, the other is the low quadword of an `XMM' register.

   The operation of this instruction is:

        mem(0-63)   := xmm(0-63);

   or

        xmm(0-63)   := mem(0-63);
        xmm(64-127) remains unchanged.

B.4.169. `MOVMSKPD': Extract Packed Double-Precision FP Sign Mask
-----------------------------------------------------------------

     MOVMSKPD reg32,xmm              ; 66 0F 50 /r   [WILLAMETTE,SSE2]

   `MOVMSKPD' inserts a 2-bit mask in r32, formed of the most
significant bits of each double-precision FP number of the source
operand.

B.4.170. `MOVMSKPS': Extract Packed Single-Precision FP Sign Mask
-----------------------------------------------------------------

     MOVMSKPS reg32,xmm              ; 0F 50 /r      [KATMAI,SSE]

   `MOVMSKPS' inserts a 4-bit mask in r32, formed of the most
significant bits of each single-precision FP number of the source
operand.

B.4.171. `MOVNTDQ': Move Double Quadword Non Temporal
-----------------------------------------------------

     MOVNTDQ m128,xmm              ; 66 0F E7 /r     [WILLAMETTE,SSE2]

   `MOVNTDQ' moves the double quadword from the `XMM' source register
to the destination memory location, using a non-temporal hint.  This
store instruction minimizes cache pollution.

B.4.172. `MOVNTI': Move Doubleword Non Temporal
-----------------------------------------------

     MOVNTI m32,reg32              ; 0F C3 /r        [WILLAMETTE,SSE2]

   `MOVNTI' moves the doubleword in the source register to the
destination memory location, using a non-temporal hint. This store
instruction minimizes cache pollution.

B.4.173. `MOVNTPD': Move Aligned Four Packed Single-Precision FP Values Non Temporal
------------------------------------------------------------------------------------

     MOVNTPD m128,xmm              ; 66 0F 2B /r     [WILLAMETTE,SSE2]

   `MOVNTPD' moves the double quadword from the `XMM' source register
to the destination memory location, using a non-temporal hint.  This
store instruction minimizes cache pollution. The memory location must
be aligned to a 16-byte boundary.

B.4.174. `MOVNTPS': Move Aligned Four Packed Single-Precision FP Values Non Temporal
------------------------------------------------------------------------------------

     MOVNTPS m128,xmm              ; 0F 2B /r        [KATMAI,SSE]

   `MOVNTPS' moves the double quadword from the `XMM' source register
to the destination memory location, using a non-temporal hint.  This
store instruction minimizes cache pollution. The memory location must
be aligned to a 16-byte boundary.

B.4.175. `MOVNTQ': Move Quadword Non Temporal
---------------------------------------------

     MOVNTQ m64,mm                 ; 0F E7 /r        [KATMAI,MMX]

   `MOVNTQ' moves the quadword in the `MMX' source register to the
destination memory location, using a non-temporal hint. This store
instruction minimizes cache pollution.

B.4.176. `MOVQ': Move Quadword to/from MMX Register
---------------------------------------------------

     MOVQ mm1,mm2/m64               ; 0F 6F /r             [PENT,MMX]
     MOVQ mm1/m64,mm2               ; 0F 7F /r             [PENT,MMX]

     MOVQ xmm1,xmm2/m64             ; F3 0F 7E /r    [WILLAMETTE,SSE2]
     MOVQ xmm1/m64,xmm2             ; 66 0F D6 /r    [WILLAMETTE,SSE2]

   `MOVQ' copies 64 bits from its source (second) operand into its
destination (first) operand. When the source is an `XMM' register, the
low quadword is moved. When the destination is an `XMM' register, the
destination is the low quadword, and the high quadword is cleared.

B.4.177. `MOVQ2DQ': Move Quadword from MMX to XMM register.
-----------------------------------------------------------

     MOVQ2DQ xmm,mm                ; F3 OF D6 /r     [WILLAMETTE,SSE2]

   `MOVQ2DQ' moves the quadword from the source operand to the low
quadword of the destination operand, and clears the high quadword.

B.4.178. `MOVSB', `MOVSW', `MOVSD': Move String
-----------------------------------------------

     MOVSB                         ; A4                   [8086]
     MOVSW                         ; o16 A5               [8086]
     MOVSD                         ; o32 A5               [386]

   `MOVSB' copies the byte at `[DS:SI]' or `[DS:ESI]' to `[ES:DI]' or
`[ES:EDI]'. It then increments or decrements (depending on the
direction flag: increments if the flag is clear, decrements if it is
set) `SI' and `DI' (or `ESI' and `EDI').

   The registers used are `SI' and `DI' if the address size is 16 bits,
and `ESI' and `EDI' if it is 32 bits. If you need to use an address
size not equal to the current `BITS' setting, you can use an explicit
`a16' or `a32' prefix.

   The segment register used to load from `[SI]' or `[ESI]' can be
overridden by using a segment register name as a prefix (for example,
`es movsb'). The use of `ES' for the store to `[DI]' or `[EDI]' cannot
be overridden.

   `MOVSW' and `MOVSD' work in the same way, but they copy a word or a
doubleword instead of a byte, and increment or decrement the addressing
registers by 2 or 4 instead of 1.

   The `REP' prefix may be used to repeat the instruction `CX' (or
`ECX' - again, the address size chooses which) times.

B.4.179. `MOVSD': Move Scalar Double-Precision FP Value
-------------------------------------------------------

     MOVSD xmm1,xmm2/m64           ; F2 0F 10 /r     [WILLAMETTE,SSE2]
     MOVSD xmm1/m64,xmm2           ; F2 0F 11 /r     [WILLAMETTE,SSE2]

   `MOVSD' moves a double-precision FP value from the source operand to
the destination operand. When the source or destination is a register,
the low-order FP value is read or written.

B.4.180. `MOVSS': Move Scalar Single-Precision FP Value
-------------------------------------------------------

     MOVSS xmm1,xmm2/m32           ; F3 0F 10 /r     [KATMAI,SSE]
     MOVSS xmm1/m32,xmm2           ; F3 0F 11 /r     [KATMAI,SSE]

   `MOVSS' moves a single-precision FP value from the source operand to
the destination operand. When the source or destination is a register,
the low-order FP value is read or written.

B.4.181. `MOVSX', `MOVZX': Move Data with Sign or Zero Extend
-------------------------------------------------------------

     MOVSX reg16,r/m8              ; o16 0F BE /r         [386]
     MOVSX reg32,r/m8              ; o32 0F BE /r         [386]
     MOVSX reg32,r/m16             ; o32 0F BF /r         [386]

     MOVZX reg16,r/m8              ; o16 0F B6 /r         [386]
     MOVZX reg32,r/m8              ; o32 0F B6 /r         [386]
     MOVZX reg32,r/m16             ; o32 0F B7 /r         [386]

   `MOVSX' sign-extends its source (second) operand to the length of its
destination (first) operand, and copies the result into the destination
operand. `MOVZX' does the same, but zero-extends rather than sign-
extending.

B.4.182. `MOVUPD': Move Unaligned Packed Double-Precision FP Values
-------------------------------------------------------------------

     MOVUPD xmm1,xmm2/mem128       ; 66 0F 10 /r     [WILLAMETTE,SSE2]
     MOVUPD xmm1/mem128,xmm2       ; 66 0F 11 /r     [WILLAMETTE,SSE2]

   `MOVUPD' moves a double quadword containing 2 packed double-precision
FP values from the source operand to the destination. This instruction
makes no assumptions about alignment of memory operands.

   To move data in and out of memory locations that are known to be on
16-byte boundaries, use the `MOVAPD' instruction (see Section B.4.157).

B.4.183. `MOVUPS': Move Unaligned Packed Single-Precision FP Values
-------------------------------------------------------------------

     MOVUPS xmm1,xmm2/mem128       ; 0F 10 /r        [KATMAI,SSE]
     MOVUPS xmm1/mem128,xmm2       ; 0F 11 /r        [KATMAI,SSE]

   `MOVUPS' moves a double quadword containing 4 packed single-precision
FP values from the source operand to the destination. This instruction
makes no assumptions about alignment of memory operands.

   To move data in and out of memory locations that are known to be on
16-byte boundaries, use the `MOVAPS' instruction (see Section B.4.158).

B.4.184. `MUL': Unsigned Integer Multiply
-----------------------------------------

     MUL r/m8                      ; F6 /4                [8086]
     MUL r/m16                     ; o16 F7 /4            [8086]
     MUL r/m32                     ; o32 F7 /4            [386]

   `MUL' performs unsigned integer multiplication. The other operand to
the multiplication, and the destination operand, are implicit, in the
following way:

   * For `MUL r/m8', `AL' is multiplied by the given operand; the
     product is stored in `AX'.

   * For `MUL r/m16', `AX' is multiplied by the given operand; the
     product is stored in `DX:AX'.

   * For `MUL r/m32', `EAX' is multiplied by the given operand; the
     product is stored in `EDX:EAX'.

   Signed integer multiplication is performed by the `IMUL' instruction:
see Section B.4.118.

B.4.185. `MULPD': Packed Single-FP Multiply
-------------------------------------------

     MULPD xmm1,xmm2/mem128        ; 66 0F 59 /r     [WILLAMETTE,SSE2]

   `MULPD' performs a SIMD multiply of the packed double-precision FP
values in both operands, and stores the results in the destination
register.

B.4.186. `MULPS': Packed Single-FP Multiply
-------------------------------------------

     MULPS xmm1,xmm2/mem128        ; 0F 59 /r        [KATMAI,SSE]

   `MULPS' performs a SIMD multiply of the packed single-precision FP
values in both operands, and stores the results in the destination
register.

B.4.187. `MULSD': Scalar Single-FP Multiply
-------------------------------------------

     MULSD xmm1,xmm2/mem32         ; F2 0F 59 /r     [WILLAMETTE,SSE2]

   `MULSD' multiplies the lowest double-precision FP values of both
operands, and stores the result in the low quadword of xmm1.

B.4.188. `MULSS': Scalar Single-FP Multiply
-------------------------------------------

     MULSS xmm1,xmm2/mem32         ; F3 0F 59 /r     [KATMAI,SSE]

   `MULSS' multiplies the lowest single-precision FP values of both
operands, and stores the result in the low doubleword of xmm1.