lzcnt
Count Leading Zeros
LZCNT r, r/m
Counts number of leading zeros.
Pseudocode Operation
count ← 0;
for i ← (width - 1) down to 0:
if (src >> i) & 1 == 1:
break;
count ← count + 1;
if src == 0:
dest ← width;
ZF ← 1;
else:
dest ← count;
ZF ← 0;
Example
LZCNT rax, rbx
Encoding
Binary Layout
F3
+0
0F
+1
BD
+2
Operands
-
dest
General-purpose register -
src
Register or memory operand
Related
Across architectures
Count Leading Zeros : how x86, ARM, RISC-V, and PowerISA each do this.
More in ABM/BMI
Reference
Instruction Forms
| Opcode | Instruction | Op/En | 64/32-bit Mode | CPUID | Description |
|---|---|---|---|---|---|
| F3 0F BD /r | LZCNT | RM | V/V | Count the number of leading zero bits in r/m16, return result in r16. LZCNT r16, r/m16 | |
| F3 0F BD /r | LZCNT | RM | V/V | Count the number of leading zero bits in r/m32, return result in r32. LZCNT r32, r/m32 | |
| F3 REX.W 0F BD /r | LZCNT | RM | V/N.E. | Count the number of leading zero bits in r/m64, return result in r64. LZCNT r64, r/m64 |
Description
LZCNT counts the number of leading most significant zero bits in a source operand (second operand) and returns the result in the destination (first operand). LZCNT is an extension of the BSR instruction. The key difference between the LZCNT and BSR instructions is that when the source operand is zero, LZCNT outputs the operand size to the destination operand, whereas BSR leaves the destination operand unmodified. On processors that do not support LZCNT, the instruction byte encoding is executed as BSR.
Operation
temp := OperandSize - 1 DEST := 0 WHILE (temp >= 0) AND (Bit(SRC, temp) = 0) DO temp := temp - 1 DEST := DEST+ 1 OD IF DEST = OperandSize CF := 1 ELSE CF := 0 FI IF DEST = 0 ZF := 1 ELSE ZF := 0 FI
Intel C/C++ Compiler Intrinsic Equivalent
LZCNT unsigned __int32 _lzcnt_u32(unsigned __int32 src); LZCNT unsigned __int64 _lzcnt_u64(unsigned __int64 src);
Flags Affected
ZF flag is set to 1 in case of zero output (most significant bit of the source is set), and to 0 otherwise, CF flag is set to 1 if input was zero and cleared otherwise. OF, SF, PF, and AF flags are undefined.
Exceptions
Protected Mode Exceptions
#GP(0) For an illegal memory operand effective address in the CS, DS, ES, FS or GS segments.
If the DS, ES, FS, or GS register is used to access memory and it contains a null segment
selector.
#SS(0) For an illegal address in the SS segment.
#PF (fault-code) For a page fault.
#AC(0) If alignment checking is enabled and an unaligned memory reference is made while the
current privilege level is 3.
#UD If LOCK prefix is used.
Real-Address Mode Exceptions
#GP(0) If any part of the operand lies outside of the effective address space from 0 to 0FFFFH.
#SS(0) For an illegal address in the SS segment.
#UD If LOCK prefix is used.
Virtual 8086 Mode Exceptions
#GP(0) If any part of the operand lies outside of the effective address space from 0 to 0FFFFH.
#SS(0) For an illegal address in the SS segment.
#PF (fault-code) For a page fault.
#AC(0) If alignment checking is enabled and an unaligned memory reference is made while the
current privilege level is 3.
#UD If LOCK prefix is used.
Compatibility Mode Exceptions
Same exceptions as in Protected Mode.
64-Bit Mode Exceptions
#GP(0) If the memory address is in a non-canonical form.
#SS(0) If a memory address referencing the SS segment is in a non-canonical form.
#PF (fault-code) For a page fault.
#AC(0) If alignment checking is enabled and an unaligned memory reference is made while the
current privilege level is 3.
#UD If LOCK prefix is used.
LZCNT-Count the Number of Leading Zero Bits Vol. 2A 3-579