Extensions
Forms
7 (7 Legacy)
Data
Intel XED v2026.08.23

MOVZX reads a byte or a word and writes it to a wider register with zeros above it. It is how code loads unsigned char and unsigned short values and widens them: GCC 14 at -O2 compiles a read of *p, with p an unsigned char *, to movzx eax, byte ptr [rdi]. MOVSX fills the upper bits with copies of the sign bit instead.

Which destination size

Writing a 32-bit register already clears bits 63:32, so movzx eax, byte ptr [rdi] leaves the same 64-bit value in RAX as the REX.W form movzx rax, byte ptr [rdi], in one byte less, and compilers use the 32-bit form for 64-bit results too. No MOVZX takes a 32-bit source: the zero-extension from 32 to 64 bits is a 32-bit MOV. A 16-bit destination is the odd one out, keeping bits 63:16 of its register like any other 16-bit write.

Instead of a byte or word MOV

mov al, [rdi] replaces only the low byte of RAX, so afterwards the register mixes the new byte with what it held before, and every later reader of RAX depends on both. MOVZX into a 32-bit register writes all 64 bits and leaves nothing of the old value.

The high-byte registers

MOVZX can read AH, CH, DH and BH, which makes bits 15:8 of a value two instructions away: GCC 14 and Clang 23 both compile (x >> 8) & 0xff to mov eax, edi and movzx eax, ah. Those four registers exist only in instructions without a REX prefix; with one, the same register numbers name SPL, BPL, SIL and DIL. So a MOVZX that reads AH must write one of the eight original registers, and the 64-bit form, which needs REX.W, cannot read them at all.

AT&T names

GNU’s AT&T syntax spells MOVZX with two size letters, source first: movzbl (byte to 32 bits), movzwl (word to 32 bits), movzbw, movzbq and movzwq. GCC writes movzbl and movzwl even for 64-bit results.

In the optimization guide

What the optimization guide says about MOVZX, a line per claim. Each links to the claim in the guide, with its sources and where they differ.

Out of order

  • Move elimination: Intel’s list of moves eliminated from Ivy Bridge on includes movzx from an 8-bit register other than AH, BH, CH and DH into a 32-bit or 64-bit one, which Agner Fog confirmed on Ivy Bridge, and LLVM’s Alder Lake model gives that movzx a latency of zero. sources differ
  • Partial register and flag writes: Writing whole registers avoids the question on every core: Intel advises working on 32-bit registers rather than 8-bit or 16-bit ones, loading bytes and words with movzx, and choosing zero extension over sign extension where the value allows.

Skylake to Cooper Lake

  • Integer execution: xor, sub and the vector pxor, xorps, pandn, psub and pcmpgt of a register with itself zero it without an execution unit, four a cycle, for 32-bit and 64-bit and all vector registers.

Forms

Every encoding of MOVZX that Intel XED knows, one row per XED instruction form (iform). How to read the notation.
InstructionEncodingRequires
MOVZX r16/32/64, m8 MOVZX_GPRv_MEMb0F B6 /rBase instruction set
MOVZX r16/32/64, m16 not in 64-bit mode MOVZX_GPRv_MEMw0F B7 /rBase instruction set
MOVZX r64, m16 64-bit mode only MOVZX_GPR64_MEMwREX.W 0F B7 /rBase instruction set
MOVZX r16, m16 64-bit mode only MOVZX_GPR16_MEMw66 0F B7 /rBase instruction set
MOVZX r32, m16 64-bit mode only MOVZX_GPR32_MEMw0F B7 /rBase instruction set
MOVZX r16/32/64, r8 MOVZX_GPRv_GPR80F B6 /rBase instruction set
MOVZX r16/32/64, r16 MOVZX_GPRv_GPR160F B7 /rBase instruction set

Latency and throughput

What the scheduling models of LLVM 23.1.2 give for each form, not measurements: latency / reciprocal throughput in cycles, the ports under them. A row is a model, or models that agree; a dash, a form that its processors lack. Memory forms: latency from the address, ports without the load and store units. Which processors each model covers.
Modelr16, m8r32, m8
r64, m8
r64, m16
r32, m16
r16, r8r32, r8
r64, r8
r32, r16
r64, r16
Sandy Bridge5 / 0.5p235 / 0.5p231 / 0.33p0151 / 0.33p0151 / 0.33p015
Haswell, Broadwell, Skylake, Skylake-SP, Ice Lake5 / 0.5p235 / 0.5p231 / 0.25p01561 / 0.25p01561 / 0.25p0156
Alder Lake, Sapphire Rapids6 / 0.33p0 p1 p5 p6 p115 / 0.33p2 p3 p101 / 0.2p0 p1 p5 p6 p110 / 0.2p0 p1 p5 p6 p111 / 0.2p0 p1 p5 p6 p11
Lunar Lake6 / 0.33p0123454 / 0.33p20 p21 p221 / 0.33p1350 / 0.17p0123451 / 0.33p135
Bonnell3 / 1.5p11 / 1p02 / 1p011 / 1p01 / 1p0
Silvermont3 / 1MEC3 / 1MEC1 / 0.5IEC0 IEC11 / 0.5IEC0 IEC11 / 0.5IEC0 IEC1
Piledriver5 / 1AGLU01 Load5 / 1AGLU01 Load1 / 1EX0 EX11 / 1EX0 EX11 / 1EX0 EX1
Zen4 / 0.5AGU0 AGU14 / 0.5AGU0 AGU11 / 0.25ALU0 ALU1 ALU2 ALU31 / 0.25ALU0 ALU1 ALU2 ALU31 / 0.25ALU0 ALU1 ALU2 ALU3
Zen 24 / 0.33AGU0 AGU1 AGU24 / 0.33AGU0 AGU1 AGU21 / 0.25ALU0 ALU1 ALU2 ALU31 / 0.25ALU0 ALU1 ALU2 ALU31 / 0.25ALU0 ALU1 ALU2 ALU3
Zen 3, Zen 45 / 1AGU0 AGU1 AGU2 LSU Load5 / 0.33AGU0 AGU1 AGU2 LSU Load1 / 1ALU0 ALU1 ALU2 ALU31 / 0.25ALU0 ALU1 ALU2 ALU31 / 0.25ALU0 ALU1 ALU2 ALU3
Jaguar3 / 1LAGU3 / 1LAGU1 / 0.5ALU0 ALU11 / 0.5ALU0 ALU11 / 0.5ALU0 ALU1

Operation

What the forms do, in pseudocode that our tests run against results recorded on real processors. How to read.

dest.write(src)                  # zero-extended to OSIZE: a 16-bit register
                                 # keeps bits 63:16, a 32-bit one gets
                                 # bits 63:32 cleared

Run on AMD Zen 5 (EPYC 9645) and an Intel processor under KVM (model hidden): 168 cases. The forms that 64-bit mode lacks were not run: the probe runs in 64-bit mode.

Operands

What each form reads and writes, as Intel XED records it: the operands of its syntax, in order, and the implicit ones that the syntax does not name. How to read.
OperandKindAction
MOVZX r16/32/64, r/m8 MOVZX r16/32/64, m16 not in 64-bit mode MOVZX r16, m16 64-bit mode only MOVZX r32, m16 64-bit mode only MOVZX r64, m16 64-bit mode only
r16/32/64explicitwrite
r/m8, m16explicitread
MOVZX r16/32/64, r16
r16/32/64explicitwrite
r16explicitread

Flags

None: XED records no flag that the forms test or change.

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.

CPUID requirements and processors of the XED ISA sets above. Alternatives are separated by “or”; processors follow XED’s chip model, whose AMD processors end with Zen 2, and the CPU data of this site for Zen 3 to Zen 6.
ISA setCPUIDProcessors
I386

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

All 109 General-purpose instructions

Sources

  1. Intel XED v2026.08.23 (commit 0bcb6237345c): forms, encodings, operands, flags, exception classes, attributes, ISA sets, CPUID bits and chip model.
  2. The CPU data of x86-64.net: Zen 3 to Zen 6, from GCC’s -march feature sets and AMD’s Processor Programming References, which the page of each processor cites.
  3. LLVM 23.1.2's x86 scheduling models (commit 85ac56026243): the latency, reciprocal throughput and ports of each form, as llvm-mca reports them.
  4. Intel 64 and IA-32 Architectures Software Developer's Manual, Volume 2 (325383-093, September 2026): Volume 2B, page 4-130 (MOVZX)
  5. Intel 64 and IA-32 Architectures Software Developer's Manual, Volume 1 (253665-093, September 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.