Instruction
MOV
Copies data between registers, memory and immediates, and moves segment, control and debug registers; those last two only in ring 0.
- Extensions
- Forms
- 30 (30 Legacy)
- Data
- Intel XED v2026.08.23
MOV is the plain copy: register to register, memory to register, register or immediate to memory. No form copies memory to memory; MOVS does that, or two MOVs through a register.
Upper bits
Writing a 32-bit register clears bits 63:32, while writing an 8- or
16-bit register keeps the bits above it. So a 32-bit MOV widens an
unsigned 32-bit value to 64 bits (GCC 14 and Clang 23 at -O2 compile
(uint64_t)x to mov eax, edi), and MOVZX has no
32-to-64-bit form;
MOVSXD is the signed counterpart.
Constants
A 64-bit register can take a constant in three encodings, and compilers pick the shortest that fits:
- B8+r without REX.W, 5 bytes: a 32-bit immediate, zero-extended, for
0 to 4,294,967,295 (
mov eax, 1). - C7 /0 with REX.W, 7 bytes: a 32-bit immediate, sign-extended, for
-2,147,483,648 to -1 (
mov rax, -1). - B8+r with REX.W, 10 bytes: all 64 bits, the form GNU assemblers write
as
movabs.
The moffs forms, A0 to A3, also take an 8-byte constant: an absolute address in place of ModRM, with AL, AX, EAX or RAX only.
Atomicity and ordering
An aligned load or store of 1, 2, 4 or 8 bytes is atomic on both
vendors’ processors. For unaligned ones the manuals differ: Intel
guarantees atomicity within a cache line (P6 and later), AMD only
within an aligned quadword. Because x86 keeps loads in order with
loads, and stores in order with stores and earlier loads, a plain MOV
is already an acquire load or a release store, and both compilers
emit MOV for C11’s atomic_load even in its sequentially consistent
form. A later load may still pass an earlier store, so for a
sequentially consistent atomic_store both emit XCHG,
whose implicit lock forbids that.
System registers
The forms for control and debug registers belong to the kernel (CPL 0), and the vendors differ again: on AMD processors that report CPUID Fn8000_0001_ECX[4] (AltMovCr8), a LOCK prefix turns MOV to or from CR0 into the same move for CR8, the task-priority register, which 32-bit code cannot otherwise name; Intel’s manual lists the LOCK prefix as #UD for these forms.
In the optimization guide
What the optimization guide says about MOV, a line per claim. Each links to the claim in the guide, with its sources and where they differ.
Front end
- Macro-fusion: Newer cores also fuse a register move with the operation after it, which gives the non-destructive three-operand form that the instruction set lacks: Zen 5 for operations on registers and immediates, and Intel’s Redwood Cove for a move or a load followed by an operation, though only when the code runs from the micro-op cache.
Out of order
- Move elimination: A register-to-register copy can be made at renaming, by pointing the destination at the physical register of the source; the move then has no latency and uses no execution unit.
- Move elimination: Moves into 8-bit, 16-bit and MMX registers are not eliminated, nor on Intel’s cores a register moved onto itself such as
mov eax, eax, and on Intel’s cores elimination can fail when its resources run short. - Partial register and flag writes: A write to AL, AH or AX, such as
mov al, [rsi], keeps the rest of RAX, so its result must be merged with the old value.
Crestmont and Gracemont
- Integer execution: Moves, NOPs and zeroing idioms are handled at allocation and may never execute.
Golden Cove and Raptor Cove
- Integer execution: Register-to-register moves and zeroing idioms are handled when micro-ops are renamed, and adding a small constant to a register sometimes takes no cycle either.
Ice Lake to Rocket Lake
- Integer execution: On Ice Lake, moves between general registers are no longer removed at renaming, and zeroing idioms take an execution unit. sources differ
Redwood Cove
- Front end: A register-to-register
movfollowed by an operation that overwrites the moved-to register, asmov rax, rbxthensub rax, rcx, becomes one micro-op computingrbx - rcxinto RAX: the three-operand form the instruction set lacks, with one slot from the queue to retirement. - Front end: Redwood Cove fuses a load into a register with the operation on that register that follows it.
- Front end: Redwood Cove’s load-and-operate fusion takes only some loads, addresses and operations.
Skylake to Cooper Lake
- Integer execution:
xor,suband the vectorpxor,xorps,pandn,psubandpcmpgtof a register with itself zero it without an execution unit, four a cycle, for 32-bit and 64-bit and all vector registers.
Zen and Zen+
- Integer execution: Register-to-register moves of 32-bit and 64-bit general registers and of XMM registers, and
xchgof general registers, take no execution cycle, while a YMM move renames only its lower half and moves the upper one in a pipe. sources differ
Zen 2
- Integer execution: Register-to-register moves of general registers of 32 and 64 bits,
xchgof them and moves of whole XMM and YMM registers take no execution cycle, where Zen 1 moves the upper half of a YMM register in a pipe. sources differ
Zen 3
- Integer execution: Register-to-register moves of general registers of 32 and 64 bits,
xchgof them and moves of whole XMM and YMM registers take no execution cycle, nor do the zeroing idioms such asxor eax, eaxandvpxor, which also break the dependency on the old value;sbb eax, eaxdepends only on the carry flag, andpcmpeqd xmm0, xmm0sets all ones without waiting. sources differ
Zen 4
- Integer execution: Register-to-register moves of general registers of 32 and 64 bits,
xchgof them and moves of whole vector registers take no execution cycle, nor do the zeroing idioms such asxor eax, eaxandvpxor, which also break the dependency on the old value;sbb eax, eaxdepends only on the carry flag. sources differ
Zen 5
- Integer execution: New in Zen 5, a register-to-register
movfuses with a following ALU instruction that writes the same register and reads only registers or an immediate, as inmov eax, edithenadd eax, esi. - Integer execution: Register-to-register moves of 32-bit and 64-bit general registers and of whole vector registers take no execution cycle, nor do the zeroing idioms such as
xor eax, eaxandvpxor, which also break the dependency on the old value.
Forms
| Instruction | Encoding | Requires |
|---|---|---|
MOV r8, imm8
MOV_GPR8_IMMb_C6r0 | C6 /0 ib | Base instruction set |
MOV m8, imm8
MOV_MEMb_IMMb | C6 /0 ib | Base instruction set |
MOV r16/32/64, imm16/32
MOV_GPRv_IMMz | C7 /0 iw/id | Base instruction set |
MOV m16/32/64, imm16/32
MOV_MEMv_IMMz | C7 /0 iw/id | Base instruction set |
MOV r8, r8
MOV_GPR8_GPR8_88 | 88 /r | Base instruction set |
MOV m8, r8
MOV_MEMb_GPR8 | 88 /r | Base instruction set |
MOV m16/32/64, r16/32/64
MOV_MEMv_GPRv | 89 /r | Base instruction set |
MOV r16/32/64, r16/32/64
MOV_GPRv_GPRv_89 | 89 /r | Base instruction set |
MOV r8, m8
MOV_GPR8_MEMb | 8A /r | Base instruction set |
MOV r8, r8
MOV_GPR8_GPR8_8A | 8A /r | Base instruction set |
MOV r16/32/64, m16/32/64
MOV_GPRv_MEMv | 8B /r | Base instruction set |
MOV r16/32/64, r16/32/64
MOV_GPRv_GPRv_8B | 8B /r | Base instruction set |
MOV m16, sreg
MOV_MEMw_SEG | 8C /r | Base instruction set |
MOV r16/32/64, sreg
MOV_GPRv_SEG | 8C /r | Base instruction set |
MOV sreg, m16
MOV_SEG_MEMw | 8E /r | Base instruction set |
MOV sreg, r16
MOV_SEG_GPR16 | 8E /r | Base instruction set |
MOV AL, m8
MOV_AL_MEMb | A0 moffs | Base instruction set |
MOV rAX, m16/32/64
MOV_OrAX_MEMv | A1 moffs | Base instruction set |
MOV m8, AL
MOV_MEMb_AL | A2 moffs | Base instruction set |
MOV m16/32/64, rAX
MOV_MEMv_OrAX | A3 moffs | Base instruction set |
MOV r8, imm8
MOV_GPR8_IMMb_B0 | B0+r ib | Base instruction set |
MOV r16/32/64, imm16/32/64
MOV_GPRv_IMMv | B8+r iw/id/io | Base instruction set |
MOV cr, r32 not in 64-bit mode
MOV_CR_CR_GPR32 | 0F 22 /r | Base instruction set |
MOV cr, r64 64-bit mode only
MOV_CR_CR_GPR64 | 0F 22 /r | Base instruction set |
MOV r32, cr not in 64-bit mode
MOV_CR_GPR32_CR | 0F 20 /r | Base instruction set |
MOV r64, cr 64-bit mode only
MOV_CR_GPR64_CR | 0F 20 /r | Base instruction set |
MOV dr, r32 not in 64-bit mode
MOV_DR_DR_GPR32 | 0F 23 /r | Base instruction set |
MOV dr, r64 64-bit mode only
MOV_DR_DR_GPR64 | 0F 23 /r | Base instruction set |
MOV r32, dr not in 64-bit mode
MOV_DR_GPR32_DR | 0F 21 /r | Base instruction set |
MOV r64, dr 64-bit mode only
MOV_DR_GPR64_DR | 0F 21 /r | Base instruction set |
Latency and throughput
| Model | m8, imm8m8, r8 | r64, imm32r32, imm32 | m16, imm16m32, imm32m64, imm32m16, r16m32, r32m64, r64 | r8, r8r16, r16r8, imm8r16, imm16r64, imm64 | r32, r32 | r64, r64 | r8, m8 | r16, m16 | r32, m32r64, m64 | m16, sreg | r32, sregr64, sreg | sreg, m16 | sreg, r16 | AL, m8 | rAX, m16 | rAX, m32rAX, m64 | m8, ALm32, rAXm64, rAX | m16, rAX | cr, r64 | r64, cr | dr, r64 | r64, dr |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Sandy Bridge | 1 / 1p4 p23 | 1 / 0.33p015 | 1 / 1p4 p23 | 1 / 0.33p015 | 1 / 0.33p015 | 1 / 0.33p015 | 5 / 0.5p23 | 5 / 0.5p23 | 5 / 0.5p23 | 1 / 0.33p015 | 1 / 0.33p015 | 6 / 1p5 | 1 / 0.33p015 | 1 / 0.33p015 | 1 / 0.33p015 | 1 / 0.33p015 | 1 / 0.33p015 | 1 / 0.33p015 | 100 / 0.33p015 | 100 / 0.33p015 | 100 / 0.33p015 | 100 / 0.33p015 |
| Haswell, Broadwell, Skylake, Skylake-SP | 1 / 1p2347 | 1 / 0.25p0156 | 1 / 1p2347 | 1 / 0.25p0156 | 1 / 0.25p0156 | 1 / 0.25p0156 | 5 / 0.5p23 | 5 / 0.5p23 | 5 / 0.5p23 | 1 / 0.25p0156 | 1 / 0.25p0156 | 1 / 0.25p0156 | 1 / 0.25p0156 | 1 / 0.25p0156 | 1 / 0.25p0156 | 1 / 0.25p0156 | 1 / 0.25p0156 | 1 / 0.25p0156 | 100 / 0.25p0156 | 100 / 0.25p0156 | 100 / 0.25p0156 | 100 / 0.25p0156 |
| Ice Lake | 1 / 0.5p4789 | 1 / 0.25p0156 | 1 / 0.5p4789 | 1 / 0.25p0156 | 1 / 0.25p0156 | 1 / 0.25p0156 | 5 / 0.5p23 | 5 / 0.5p23 | 5 / 0.5p23 | 1 / 0.25p0156 | 1 / 0.25p0156 | 1 / 0.25p0156 | 1 / 0.25p0156 | 1 / 0.25p0156 | 1 / 0.25p0156 | 1 / 0.25p0156 | 1 / 0.25p0156 | 1 / 0.25p0156 | 100 / 0.25p0156 | 100 / 0.25p0156 | 100 / 0.25p0156 | 100 / 0.25p0156 |
| Alder Lake, Sapphire Rapids | 13 / 0.5p4789 | 1 / 0.2p0 p1 p5 p6 p11 | 12 / 0.5p4789 | 1 / 0.2p0 p1 p5 p6 p11 | 0 / 0.2p0 p1 p5 p6 p11 | 1 / 0 | 6 / 0.33p0 p1 p5 p6 p11 | 6 / 0.33p0 p1 p5 p6 p11 | 5 / 0.33p2 p3 p10 | 12 / 1p1 | 1 / 1p0 p1 p5 p6 p11 | 1 / 0.25p0156 | 1 / 0.25p0156 | 1 / 0.33p0 p1 p5 p6 p11 | 5 / 0.33p0 p1 p5 p6 p11 | 1 / 0.33p2 p3 p10 | 1 / 0.5p0 p1 p5 p6 p11 | 5 / 0.5p0 p1 p5 p6 p11 | 100 / 0.25p0156 | 100 / 1p0 p1 p5 p6 p11 | 217 / 12p0 p1 p4 p5 p6 p7 p8 p9 p11 | 181 / 4.8p0 p1 p5 p6 p11 |
| Lunar Lake | 13 / 0.5p10 p11 p25 p26 p27 | 1 / 0.17p012345 | 12 / 0.5p10 p11 p25 p26 p27 | 1 / 0.17p012345 | 0 / 0.17p012345 | 1 / 0 | 6 / 0.33p012345 | 6 / 0.33p012345 | 4 / 0.33p20 p21 p22 | 12 / 0.5p135 | 1 / 0.33p012345 | 1 / 0.17p012345 | 1 / 0.17p012345 | 1 / 0.33p012345 | 5 / 0.33p012345 | 1 / 0.33p20 p21 p22 | 1 / 0.5p012345 | 5 / 0.5p012345 | 100 / 0.17p012345 | 100 / 0.5p012345 | 100 / 0.17p012345 | 100 / 0.17p012345 |
| Bonnell | 1 / 1p0 | 1 / 0.5p01 | 1 / 1p0 | 1 / 0.5p01 | 1 / 0.5p01 | 1 / 0.5p01 | 1 / 1p0 | 1 / 1p0 | 1 / 1p0 | 1 / 0.5p1 | 1 / 0.5p01 | 1 / 0.5p1 | 1 / 0.5p01 | 1 / 0.5p1 | 1 / 0.5p1 | 1 / 0.5p1 | 1 / 0.5p1 | 1 / 0.5p1 | 100 / 0.5p01 | 100 / 0.5p01 | 100 / 0.5p01 | 100 / 0.5p01 |
| Silvermont | 1 / 1IEC0 IEC1 MEC | 1 / 0.5IEC0 IEC1 | 1 / 1IEC0 IEC1 MEC | 1 / 0.5IEC0 IEC1 | 1 / 0.5IEC0 IEC1 | 1 / 0.5IEC0 IEC1 | 3 / 1MEC | 3 / 1MEC | 3 / 1MEC | 1 / 0.5IEC0 IEC1 | 1 / 0.5IEC0 IEC1 | 1 / 0.5IEC0 IEC1 | 1 / 0.5IEC0 IEC1 | 1 / 0.5IEC0 IEC1 | 1 / 0.5IEC0 IEC1 | 1 / 0.5IEC0 IEC1 | 1 / 0.5IEC0 IEC1 | 1 / 0.5IEC0 IEC1 | 100 / 1FPC0 | 100 / 1FPC0 | 100 / 1FPC0 | 100 / 1FPC0 |
| Piledriver | 1 / 1AGLU01 Store | 1 / 1EX0 EX1 | 1 / 1AGLU01 Store | 1 / 1EX0 EX1 | 1 / 1EX0 EX1 | 1 / 1EX0 EX1 | 5 / 1AGLU01 Load | 5 / 1AGLU01 Load | 5 / 1AGLU01 Load | 1 / 1EX0 EX1 | 1 / 1EX0 EX1 | 1 / 1EX0 EX1 | 1 / 1EX0 EX1 | 1 / 1EX0 EX1 | 1 / 1EX0 EX1 | 1 / 1EX0 EX1 | 1 / 1EX0 EX1 | 1 / 1EX0 EX1 | 100 / 0.5EX0 EX1 | 100 / 0.5EX0 EX1 | 100 / 0.5EX0 EX1 | 100 / 0.5EX0 EX1 |
| Zen | 1 / 0.5AGU0 AGU1 | 1 / 0.25ALU0 ALU1 ALU2 ALU3 | 1 / 0.5AGU0 AGU1 | 1 / 0.25ALU0 ALU1 ALU2 ALU3 | 1 / 0.25ALU0 ALU1 ALU2 ALU3 | 1 / 0.25ALU0 ALU1 ALU2 ALU3 | 4 / 0.5AGU0 AGU1 | 5 / 0.5ALU0 ALU1 ALU2 ALU3 | 4 / 0.5AGU0 AGU1 | 1 / 0.25ALU0 ALU1 ALU2 ALU3 | 1 / 0.25ALU0 ALU1 ALU2 ALU3 | 1 / 0.25ALU0 ALU1 ALU2 ALU3 | 1 / 0.25ALU0 ALU1 ALU2 ALU3 | 1 / 0.25ALU0 ALU1 ALU2 ALU3 | 1 / 0.25ALU0 ALU1 ALU2 ALU3 | 1 / 0.25ALU0 ALU1 ALU2 ALU3 | 1 / 0.25ALU0 ALU1 ALU2 ALU3 | 1 / 0.25ALU0 ALU1 ALU2 ALU3 | 100 / 0.25 | 100 / 0.25 | 100 / 0.25 | 100 / 0.25 |
| Zen 2 | 1 / 0.33AGU0 AGU1 AGU2 | 1 / 0.25ALU0 ALU1 ALU2 ALU3 | 1 / 0.33AGU0 AGU1 AGU2 | 1 / 0.25ALU0 ALU1 ALU2 ALU3 | 1 / 0.25ALU0 ALU1 ALU2 ALU3 | 1 / 0.25ALU0 ALU1 ALU2 ALU3 | 4 / 0.33AGU0 AGU1 AGU2 | 5 / 0.33ALU0 ALU1 ALU2 ALU3 | 4 / 0.33AGU0 AGU1 AGU2 | 1 / 0.25ALU0 ALU1 ALU2 ALU3 | 1 / 0.25ALU0 ALU1 ALU2 ALU3 | 1 / 0.25ALU0 ALU1 ALU2 ALU3 | 1 / 0.25ALU0 ALU1 ALU2 ALU3 | 1 / 0.25ALU0 ALU1 ALU2 ALU3 | 1 / 0.25ALU0 ALU1 ALU2 ALU3 | 1 / 0.25ALU0 ALU1 ALU2 ALU3 | 1 / 0.25ALU0 ALU1 ALU2 ALU3 | 1 / 0.25ALU0 ALU1 ALU2 ALU3 | 100 / 0.25 | 100 / 0.25 | 100 / 0.25 | 100 / 0.25 |
| Zen 3, Zen 4 | 1 / 1AGU0 AGU1 AGU2 LSU Store | 1 / 0.5ALU0 ALU1 ALU2 ALU3 | 1 / 1AGU0 AGU1 AGU2 LSU Store | 1 / 1ALU0 ALU1 ALU2 ALU3 | 0 / 0.17 | 0 / 0.17 | 5 / 1AGU0 AGU1 AGU2 LSU Load | 5 / 1AGU0 AGU1 AGU2 LSU Load | 5 / 0.33AGU0 AGU1 AGU2 LSU Load | 1 / 1ALU0 ALU1 ALU2 ALU3 | 1 / 1ALU0 ALU1 ALU2 ALU3 | 1 / 1ALU0 ALU1 ALU2 ALU3 | 1 / 1ALU0 ALU1 ALU2 ALU3 | 1 / 0.25ALU0 ALU1 ALU2 ALU3 | 1 / 0.25ALU0 ALU1 ALU2 ALU3 | 1 / 0.25ALU0 ALU1 ALU2 ALU3 | 1 / 0.25ALU0 ALU1 ALU2 ALU3 | 1 / 0.25ALU0 ALU1 ALU2 ALU3 | 100 / 25ALU0 ALU1 ALU2 ALU3 | 100 / 25ALU0 ALU1 ALU2 ALU3 | 100 / 25ALU0 ALU1 ALU2 ALU3 | 100 / 25ALU0 ALU1 ALU2 ALU3 |
| Jaguar | 1 / 1SAGU | 1 / 0.5ALU0 ALU1 | 1 / 1SAGU | 1 / 0.5ALU0 ALU1 | 1 / 0.5ALU0 ALU1 | 1 / 0.5ALU0 ALU1 | 3 / 1LAGU | 3 / 1LAGU | 3 / 1LAGU | 1 / 0.5ALU0 ALU1 | 1 / 0.5ALU0 ALU1 | 1 / 0.5ALU0 ALU1 | 1 / 0.5ALU0 ALU1 | 1 / 0.5ALU0 ALU1 | 1 / 0.5ALU0 ALU1 | 1 / 0.5ALU0 ALU1 | 1 / 0.5ALU0 ALU1 | 1 / 0.5ALU0 ALU1 | 100 / 0.5ALU0 ALU1 | 100 / 0.5ALU0 ALU1 | 100 / 0.5ALU0 ALU1 | 100 / 0.5ALU0 ALU1 |
Operation
What the forms do, in pseudocode that our tests run against results recorded on real processors. How to read.
MOV r/m8, imm8 MOV r/m8, r8 MOV r8, r/m8 MOV AL, m8 MOV m8, AL MOV r/m16/32/64, imm16/32 MOV r/m16/32/64, r16/32/64 MOV r16/32/64, r/m16/32/64 MOV rAX, m16/32/64 MOV m16/32/64, rAX MOV r16/32/64, imm16/32/64v = sext(src) # only an imm32 to a 64-bit operand is
# sign-extended; imm64 fills all 64 bits
dest.write(v) # a 32-bit register: bits 63:32 cleared
Run on AMD Zen 5 (EPYC 9645) and an Intel processor under KVM (model hidden): 358 cases.
MOV m16, sreg MOV r16/32/64, sregdest.write(src) # the 16-bit selector: m16 whatever the
# operand size; a 32- or 64-bit register
# gets it zero-extended, a 16-bit one
# keeps bits 63:16
Run on AMD Zen 5 (EPYC 9645) and an Intel processor under KVM (model hidden): 72 cases.
MOV sreg, r/m16if dest.number == 1:
fault(UD) # MOV cannot load CS
load_segment(dest, src) # checks the descriptor the selector
# names: #GP(sel), #SS(sel), #NP(sel)
# FS and GS also take its base, or 0 with a null selector (Zen 5,
# as AMD's NullSelectorClearsBase has it)
# after MOV SS, interrupts and most debug exceptions wait until
# the next instruction is done, so that it can load RSPRun on AMD Zen 5 (EPYC 9645): 57 cases.
MOV cr, r32 not in 64-bit mode MOV cr, r64 64-bit mode onlyn = dest.number
if n not in (0, 2, 3, 4, 8):
fault(UD) # CR1, CR5 to CR7 and CR9 to CR15
if CPL != 0:
fault(GP, 0)
v = src.read() # MOV cr, r32 (outside 64-bit mode):
# zero-extended to 64 bits
if n == 0:
if v >> 32 != 0:
fault(GP, 0) # bits 63:32 are reserved
if (v >> 29 & 3) == 1:
fault(GP, 0) # NW set with CD clear
if v >> 31 == 0:
fault(GP, 0) # PG clear, which 64-bit mode forbids
if cr4 >> 23 & 1 and (v >> 16 & 1) == 0:
fault(GP, 0) # WP clear while CR4.CET is set
if n == 3 and cr4 >> 17 & 1:
v &= ~(1 << 63) # with PCIDE, bit 63 set keeps the TLB
# entries of the PCID; it is not stored
if n == 4:
if (v >> 5 & 1) == 0:
fault(GP, 0) # PAE clear (64-bit mode)
if (v ^ cr4) >> 12 & 1:
fault(GP, 0) # LA57 changed (64-bit mode)
if (cr4 >> 17 & 1) == 0 and v >> 17 & 1:
if cr3 & 0xFFF:
fault(GP, 0) # PCIDE set while CR3 names a PCID
if v >> 23 & 1 and (cr0 >> 16 & 1) == 0:
fault(GP, 0) # CET set while CR0.WP is clear
if n == 8 and v >> 4 != 0:
fault(GP, 0) # CR8 is the 4-bit task priority
# also #GP(0) for a 1 in a bit the processor reserves: CR3 bits
# from MAXPHYADDR up, CR4 bits of features it lacks
dest.write(v) # CR0, CR3 and CR4 writes can flush TLBs
of = sf = zf = af = pf = cf = UNDEFINEDNot run on a processor: control registers can be written at CPL 0 only.
MOV r32, cr not in 64-bit mode MOV r64, cr 64-bit mode onlyif src.number not in (0, 2, 3, 4, 8):
fault(UD) # CR1, CR5 to CR7 and CR9 to CR15
if CPL != 0:
fault(GP, 0)
dest.write(src) # CR8 reads as the task priority, bits
# 3:0; MOV r32, cr keeps bits 31:0
of = sf = zf = af = pf = cf = UNDEFINEDNot run on a processor: control registers can be read at CPL 0 only.
MOV dr, r32 not in 64-bit mode MOV dr, r64 64-bit mode onlyn = dest.number
if n > 7:
fault(UD) # DR8 to DR15 do not exist
if CPL != 0:
fault(GP, 0)
if n in (4, 5) and cr4 >> 3 & 1:
fault(UD) # with CR4.DE, DR4 and DR5 do not exist
if dr7 >> 13 & 1:
fault(DB) # DR7.GD guards the debug registers
v = src.read()
if n in (4, 5):
n += 2 # otherwise they are DR6 and DR7
if n >= 6 and v >> 32 != 0:
fault(GP, 0) # bits 63:32 of DR6 and DR7 are reserved
if n == 6:
dr6 = v
elif n == 7:
dr7 = v
else:
dest.write(v)
of = sf = zf = af = pf = cf = UNDEFINEDNot run on a processor: debug registers can be written at CPL 0 only.
MOV r32, dr not in 64-bit mode MOV r64, dr 64-bit mode onlyn = src.number
if n > 7:
fault(UD) # DR8 to DR15 do not exist
if CPL != 0:
fault(GP, 0)
if n in (4, 5) and cr4 >> 3 & 1:
fault(UD) # with CR4.DE, DR4 and DR5 do not exist
if dr7 >> 13 & 1:
fault(DB) # DR7.GD guards the debug registers
if n == 4:
dest.write(dr6) # without CR4.DE, DR4 and DR5 are DR6
elif n == 5: # and DR7
dest.write(dr7)
else:
dest.write(src)
of = sf = zf = af = pf = cf = UNDEFINEDNot run on a processor: debug registers can be read at CPL 0 only.
Operands
| Operand | Kind | Action |
|---|---|---|
MOV r/m8, imm8 MOV r/m16/32/64, imm16/32 | ||
r/m8/16/32/64 | explicit | write |
imm8/16/32 | explicit | read |
MOV r/m8, r8 MOV r/m16/32/64, r16/32/64 | ||
r/m8/16/32/64 | explicit | write |
r8/16/32/64 | explicit | read |
MOV r8, r/m8 MOV r16/32/64, r/m16/32/64 | ||
r8/16/32/64 | explicit | write |
r/m8/16/32/64 | explicit | read |
MOV m16, sreg | ||
m16 | explicit | write |
sreg | explicit | read |
MOV r16/32/64, sreg | ||
r16/32/64 | explicit | write |
sreg | explicit | read |
MOV sreg, r/m16 | ||
sreg | explicit | write |
r/m16 | explicit | read |
MOV AL, m8 MOV rAX, m16/32/64 | ||
AL, rAX | explicit | write |
m8/16/32/64 | explicit | read |
MOV m8, AL MOV m16/32/64, rAX | ||
m8/16/32/64 | explicit | write |
AL, rAX | explicit | read |
MOV r16/32/64, imm16/32/64 | ||
r16/32/64 | explicit | write |
imm16/32/64 | explicit | read |
MOV cr, r32 not in 64-bit mode MOV cr, r64 64-bit mode only | ||
cr | explicit | write |
r32/64 | explicit | read |
MOV r32, cr not in 64-bit mode MOV r64, cr 64-bit mode only | ||
r32/64 | explicit | write |
cr | explicit | read |
MOV dr, r32 not in 64-bit mode MOV dr, r64 64-bit mode only | ||
dr | explicit | write |
r32/64 | explicit | read |
MOV r32, dr not in 64-bit mode MOV r64, dr 64-bit mode only | ||
r32/64 | explicit | write |
dr | explicit | read |
Flags
None: XED records no flag that the forms test or change.
Attributes
What else XED records about the forms. How to read.
MOV cr, r32not in 64-bit modeMOV r32, crnot in 64-bit modeMOV dr, r32not in 64-bit modeMOV r32, drnot in 64-bit modeMOV cr, r6464-bit mode onlyMOV r64, cr64-bit mode onlyMOV dr, r6464-bit mode onlyMOV r64, dr64-bit mode only- privileged: CPL 0 only
MOV sreg, r/m16MOV cr, r32not in 64-bit modeMOV dr, r32not in 64-bit modeMOV cr, r6464-bit mode onlyMOV dr, r6464-bit mode only- may abort a TSX transaction
MOV m8, imm8MOV m8, r8MOV m16/32/64, imm16/32MOV m16/32/64, r16/32/64- accepts XRELEASE
CPUID and processors
Each form belongs to an XED ISA set. A form can be used when the processor reports every CPUID bit of one of its ISA set's alternatives.
| ISA set | CPUID | Processors |
|---|---|---|
I86 | No CPUID bit: part of the base instruction set. | Every x86-64 processor in XED’s model and Zen 3 to Zen 6 |
More General-purpose instructions
Sources
- Intel XED v2026.08.23 (commit
0bcb6237345c): forms, encodings, operands, flags, exception classes, attributes, ISA sets, CPUID bits and chip model. - The CPU data of x86-64.net: Zen 3 to Zen 6, from GCC’s
-marchfeature sets and AMD’s Processor Programming References, which the page of each processor cites. - LLVM 23.1.2's x86 scheduling models (commit
85ac56026243): the latency, reciprocal throughput and ports of each form, as llvm-mca reports them. - Intel 64 and IA-32 Architectures Software Developer's Manual, Volume 2 (325383-093, September 2026): Volume 2B, page 4-28 (MOV); Volume 2B, page 4-32 (MOV); Volume 2B, page 4-35 (MOV)
- Intel 64 and IA-32 Architectures Software Developer's Manual, Volume 1 (253665-093, September 2026)
- Intel 64 and IA-32 Architectures Software Developer's Manual, Volume 3 (325384-093, September 2026)
- AMD64 Architecture Programmer's Manual, Volume 2: System Programming (24593, rev. 3.46, October 2026)
- AMD64 Architecture Programmer's Manual, Volume 3: General-Purpose and System Instructions (24594, rev. 3.39, October 2026)
The tables are derived from Intel XED, Copyright Intel Corporation, licensed under the Apache License 2.0; x86-64.net converted and reformatted them. The timings come from LLVM's scheduling models, part of the LLVM Project, licensed under the Apache License 2.0 with LLVM Exceptions. The text is our own.