Instruction
SCAS
Compares AL, AX, EAX or RAX with the element at [RDI], setting the flags as CMP would, and steps RDI; REPNE SCAS searches for a value.
- Extensions
- Mnemonics
- SCAS, SCASB, SCASW, SCASD, SCASQ
- Forms
- 12 (12 Legacy)
- Data
- Intel XED v2026.08.23
SCAS compares AL, AX, EAX or RAX with the element at [RDI], setting the
flags as cmp al, [rdi] would, and moves RDI to the next element. With
REPNE it searches for the value; with REPE it skips over a run of it.
REPNE SCASB as strlen and memchr
The classic strlen sets AL to 0, RCX to -1, so that the count cannot
run out, and RDI to the string, then runs repne scasb. It stops after
the terminating zero, with RDI one byte past it. RCX has gone down once
for every byte compared, the terminator included, so for a string of n
bytes it ends at -(n + 2), and not rcx followed by dec rcx leaves n.
memchr sets RCX to the length instead, and the flags tell the two
endings apart: ZF set means the byte was found, at RDI - 1; ZF clear
means the count ran out first. A length of 0 compares nothing and
changes no flag, so ZF must not be trusted without a test of RCX.
REPE SCAS stops at the first element that differs from rAX, which finds, for example, the first non-zero quadword of a buffer with RAX = 0.
Things to know
- Only ES:RDI. The element is always read through ES:RDI, and a segment prefix cannot change that; in 64-bit mode ES has base 0.
- No source pointer. RSI is neither read nor changed.
- Faults. A fault partway through leaves RDI and RCX at the element that faulted and the flags as they were before the instruction, so it resumes cleanly. The direction flag and the 67 prefix work as on the MOVS page.
Speed
GCC 14 and Clang 23 at -O2 call strlen and memchr rather than
inline a REPNE SCASB. Intel’s optimization manual advises against REP
SCAS and REP CMPS for performance and points to SIMD code instead
(Section 3.7.5), such as PCMPEQB and
PMOVMSKB over 16 bytes at a time. From Golden Cove
on, its processors report faster REPE and REPNE SCASB and CMPSB, for 1
to 128 bytes in the first-level cache, in CPUID.(EAX=7,ECX=1):EAX[12]
(Section 3.8.3). The instruction table of AMD’s Zen 5 guide lists SCASB
as microcoded.
In the optimization guide
What the optimization guide says about SCAS, a line per claim. Each links to the claim in the guide, with its sources and where they differ.
Memory
- REP MOVS and STOS: Intel’s cores made
rep movsbandrep stosbfast from Ivy Bridge, and short strings fast from Ice Lake and Golden Cove, as CPUID reports.
Golden Cove and Raptor Cove
- Loads, stores and caches: Short
rep movsb,rep stosb,rep cmpsbandrep scasbare fast: with the data in the L1 cache, any length up to 128 bytes takes a flat 9, 12, 15 and 15 cycles, zero included except for the compares.
Forms
| Instruction | Encoding | Requires |
|---|---|---|
SCASB
SCASB | AE | Base instruction set |
SCASW
SCASW | 66 AF | Base instruction set |
SCASD
SCASD | AF | Base instruction set |
SCASQ 64-bit mode only
SCASQ | REX.W AF | LM |
REPE SCASB
REPE_SCASB | F3 AE | Base instruction set |
REPNE SCASB
REPNE_SCASB | F2 AE | Base instruction set |
REPE SCASW
REPE_SCASW | 66 F3 AF | Base instruction set |
REPNE SCASW
REPNE_SCASW | 66 F2 AF | Base instruction set |
REPE SCASD
REPE_SCASD | F3 AF | Base instruction set |
REPNE SCASD
REPNE_SCASD | F2 AF | Base instruction set |
REPE SCASQ 64-bit mode only
REPE_SCASQ | F3 REX.W AF | LM |
REPNE SCASQ 64-bit mode only
REPNE_SCASQ | F2 REX.W AF | LM |
Latency and throughput
| Model | SCASBSCASWSCASDSCASQSCASBSCASBSCASWSCASWSCASDSCASDSCASQSCASQ |
|---|---|
| Sandy Bridge | 2 / 0.67p015 |
| Haswell, Broadwell, Skylake, Skylake-SP, Ice Lake | 7 / 0.5p012356 |
| Alder Lake, Sapphire Rapids | 6 / 0.6p0 p1 p2 p3 p5 p6 p10 p11 |
| Lunar Lake | 100 / 0.17p012345 |
| Bonnell | 2 / 1p01 |
| Silvermont | 100 / 1FPC0 |
| Piledriver | 100 / 0.5EX0 EX1 |
| Zen, Zen 2 | 100 / 0.25 |
| Zen 3, Zen 4 | 100 / 25ALU0 ALU1 ALU2 ALU3 |
| Jaguar | 100 / 0.5ALU0 ALU1 |
Operation
What the forms do, in pseudocode that our tests run against results recorded on real processors. How to read.
step = -(OSIZE // 8) if df else OSIZE // 8
flags = sub_flags(rAX, load(aDI, OSIZE)) # as CMP rAX, [rDI]
aDI = low(aDI + step, ASIZE)Run on AMD Zen 5 (EPYC 9645): 16 cases.
REPE SCASB REPE SCASW REPE SCASD REPE SCASQ 64-bit mode onlystep = -(OSIZE // 8) if df else OSIZE // 8
d = aDI
c = aCX
for i in range(aCX): # no flag changes when aCX is 0
v = load(d, OSIZE)
flags = sub_flags(rAX, v)
d = low(d + step, ASIZE)
c -= 1
if v != rAX:
break # ZF clear: the first difference
aDI = d
aCX = cRun on AMD Zen 5 (EPYC 9645): 24 cases.
REPNE SCASB REPNE SCASW REPNE SCASD REPNE SCASQ 64-bit mode onlystep = -(OSIZE // 8) if df else OSIZE // 8
d = aDI
c = aCX
for i in range(aCX):
v = load(d, OSIZE)
flags = sub_flags(rAX, v)
d = low(d + step, ASIZE)
c -= 1
if v == rAX:
break # ZF set: found
aDI = d
aCX = cRun on AMD Zen 5 (EPYC 9645): 24 cases.
Operands
| Operand | Kind | Action |
|---|---|---|
SCASB SCASW SCASD SCASQ 64-bit mode only | ||
AL, AX, EAX, RAX | implicit | read |
m8/16/32/64 at ES:[rDI] | implicit | read |
rDI | implicit | read, write |
RFLAGS | implicit | read, write |
REPE SCASB REPNE SCASB REPE SCASW REPNE SCASW REPE SCASD REPNE SCASD REPE SCASQ 64-bit mode only REPNE SCASQ 64-bit mode only | ||
AL, AX, EAX, RAX | implicit | read |
m8/16/32/64 at ES:[rDI] | implicit | conditional read |
rDI | implicit | read, conditional write |
rCX | implicit | read, conditional write |
RFLAGS | implicit | read, conditional write |
Flags
| When | OF | SF | ZF | AF | PF | CF | DF |
|---|---|---|---|---|---|---|---|
| REP forms | |||||||
| in some cases | M | M | TM | M | M | M | T |
| Other forms | |||||||
| M | M | M | M | M | M | T | |
Attributes
What else XED records about the forms. How to read.
- REP forms
- repeated: count in rCX
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 |
I386 | No CPUID bit: part of the base instruction set. | Every x86-64 processor in XED’s model and Zen 3 to Zen 6 |
LONGMODE | LM | 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-616 (SCAS/
SCASB/ SCASW/ SCASD) - AMD64 Architecture Programmer's Manual, Volume 3: General-Purpose and System Instructions (24594, rev. 3.39, October 2026)
- Intel 64 and IA-32 Architectures Optimization Reference Manual, Volume 1 (248966-051, October 2026)
- Software Optimization Guide for the AMD Zen5 Microarchitecture (58455, rev. 1.00, August 2024), Wayback Machine copy of AMD's ZIP
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.