Introduction
These instructions work on the bits of a general register or of memory, at the operand size. AND, OR, XOR and TEST clear OF and CF and set SF, ZF and PF from the result; AF is undefined. The shifts and rotates set CF from the last bit shifted out. NOT changes no flags.
The logical instructions and the shifts and rotates by 1 or by CL came with the 8086
in 1978; the 80186 added shifts by an immediate count, and the 80386 the double
shifts, the bit tests, the bit scans and SETcc. Intel’s APX adds, in 64-bit mode,
new-destination (NDD) and no-flags (NF) forms, and a conditional test,
ctestscc. A program checks for APX with CPUID leaf 7, sub-leaf 1, EDX
bit 21.
The newer bit instructions (POPCNT, LZCNT, TZCNT, BMI1, BMI2, TBM) are on the Bit manipulation page.
The instructions
The notation is as on the Data transfer page.
Logical operations
| Instruction | Forms | Encoding | What it does | Set |
|---|---|---|---|---|
and | r/m8, r8r/m16/32/64, r16/32/64r8, r/m8r16/32/64, r/m16/32/64AL, imm8rAX, imm16/32r/m8, imm8r/m16/32/64, imm16/32r/m16/32/64, imm8 | 20 /r21 /r22 /r23 /r24 ib25 iw/id80 /4 ib81 /4 iw/id83 /4 ibEVEX.MAP4 20–23, 80, 81, 83 /4 | Bitwise AND of the two operands, into the destination. The APX form takes ND (a new destination in EVEX.vvvv) and NF. | 8086 (Intel 8086, 1978) |
or | as and | 08–0D80, 81, 83 /1EVEX.MAP4 08–0B, 80, 81, 83 /1 | Bitwise inclusive OR. | 8086 (Intel 8086, 1978) |
xor | as and | 30–3580, 81, 83 /6EVEX.MAP4 30–33, 80, 81, 83 /6 | Bitwise exclusive OR. xor eax, eax is the usual way to clear a register. | 8086 (Intel 8086, 1978) |
not | r/m8r/m16/32/64 | F6 /2F7 /2EVEX.MAP4 F6 /2, F7 /2 | Inverts every bit (one’s complement). Changes no flags, so the APX form takes ND but not NF. | 8086 (Intel 8086, 1978) |
test | r/m8, r8r/m16/32/64, r16/32/64AL, imm8rAX, imm16/32r/m8, imm8r/m16/32/64, imm16/32 | 84 /r85 /rA8 ibA9 iw/idF6 /0 ib (and /1)F7 /0 iw/id (and /1) | ANDs the operands and sets the flags as and does, but writes no result. F6 /1 and F7 /1 are undocumented copies of /0, which processors run as TEST; the disassembler shows them as test. | 8086 (Intel 8086, 1978) |
ctestsccCondition names: ctesto, ctestno, ctestb, ctestae, cteste, ctestne, ctestbe, ctesta, ctests, ctestns, ctestt, ctestf, ctestl, ctestge, ctestle, ctestg | {dfv=…} r/m8, r8{dfv=…} r/m16/32/64, r16/32/64{dfv=…} r/m8, imm8{dfv=…} r/m16/32/64, imm16/32 | EVEX.MAP4 84 /rEVEX.MAP4 85 /rEVEX.MAP4 F6 /0 ibEVEX.MAP4 F7 /0 iw/id | Conditional test. If the source condition scc holds, tests as test; otherwise sets OF, SF, ZF and CF to the default flags value in the instruction, shown as {dfv=of,sf,zf,cf} (the flags set to 1). The condition is in EVEX P2 bits 3–0 and the default flags in EVEX.vvvv, not inverted; the conditions are those of Jcc, except that 1010 is t (always) and 1011 is f (never). TEST’s copy at /1 is not promoted. 64-bit mode only. | APX (announced for Intel Nova Lake and Diamond Rapids) |
Shifts and rotates
Group 2 holds all seven, picked by ModRM.reg: /0 ROL, /1
ROR, /2 RCL, /3 RCR, /4 SHL, /5
SHR, /7 SAR. Each comes in six opcodes: D0 and
D1 shift by 1, D2 and D3 by CL, and
C0 and C1 by an immediate byte (80186 and later); the even
one is the 8-bit form. The count is masked to 5 bits, or to 6 with a 64-bit operand
size. A count of 0 changes no flags. OF is defined only for shifts by 1. In APX the
group is promoted to EVEX map 4, with ND, and with NF except for RCL and RCR, which
read CF.
| Instruction | Forms | Encoding | What it does | Set |
|---|---|---|---|---|
rol | r/m8, 1 · r/m8, CL · r/m8, imm8r/m16/32/64, 1 · , CL · , imm8 | D0 /0, D2 /0, C0 /0 ibD1 /0, D3 /0, C1 /0 ib | Rotates left: the top bit goes into bit 0 and into CF. | 8086 (Intel 8086, 1978); the immediate count 80186 |
ror | as rol | D0–D3 /1, C0, C1 /1 ib | Rotates right: bit 0 goes into the top bit and into CF. | 8086 (Intel 8086, 1978); the immediate count 80186 |
rcl | as rol | D0–D3 /2, C0, C1 /2 ib | Rotates left through CF: the operand and CF together rotate as one value one bit wider. | 8086 (Intel 8086, 1978); the immediate count 80186 |
rcr | as rol | D0–D3 /3, C0, C1 /3 ib | Rotates right through CF. | 8086 (Intel 8086, 1978); the immediate count 80186 |
shl | as rol | D0–D3 /4, C0, C1 /4 ib (and /6) | Shifts left, filling with zeros; the last bit shifted out goes into CF. SAL is the same instruction. /6 is an undocumented copy that processors run as SHL; LLVM and the disassembler show it as shl. APX does not promote /6. | 8086 (Intel 8086, 1978); the immediate count 80186 |
shr | as rol | D0–D3 /5, C0, C1 /5 ib | Shifts right, filling with zeros: an unsigned divide by a power of two. | 8086 (Intel 8086, 1978); the immediate count 80186 |
sar | as rol | D0–D3 /7, C0, C1 /7 ib | Shifts right, filling with copies of the sign bit: a signed divide by a power of two that rounds towards minus infinity. | 8086 (Intel 8086, 1978); the immediate count 80186 |
shld | r/m16/32/64, r16/32/64, imm8r/m16/32/64, r16/32/64, CL | 0F A4 /r ib0F A5 /rEVEX.MAP4 24 /r ib, A5 /r | Double-precision shift left: shifts the destination left, filling from the top bits of the second operand, which is not changed. With a 16-bit operand size, a count above 16 gives an undefined result. The APX forms take ND and NF. | 80386 (Intel 80386, 1985) |
shrd | r/m16/32/64, r16/32/64, imm8r/m16/32/64, r16/32/64, CL | 0F AC /r ib0F AD /rEVEX.MAP4 2C /r ib, AD /r | Double-precision shift right: shifts the destination right, filling from the low bits of the second operand. | 80386 (Intel 80386, 1985) |
Bit test and bit scan
The bit tests copy one bit to CF; ZF is unchanged, and OF, SF, AF and PF are undefined. With a register bit offset and a memory operand, the offset is a signed number that can reach any bit of memory around the operand, not only bits of the operand itself.
| Instruction | Forms | Encoding | What it does | Set |
|---|---|---|---|---|
bt | r/m16/32/64, r16/32/64r/m16/32/64, imm8 | 0F A3 /r0F BA /4 ib | Copies the selected bit to CF. | 80386 (Intel 80386, 1985) |
bts | as bt | 0F AB /r0F BA /5 ib | Copies the bit to CF, then sets it. May take LOCK. | 80386 (Intel 80386, 1985) |
btr | as bt | 0F B3 /r0F BA /6 ib | Copies the bit to CF, then clears it. May take LOCK. | 80386 (Intel 80386, 1985) |
btc | as bt | 0F BB /r0F BA /7 ib | Copies the bit to CF, then inverts it. May take LOCK. | 80386 (Intel 80386, 1985) |
bsf | r16/32/64, r/m16/32/64 | 0F BC /r | Bit scan forward: writes the index of the lowest set bit of the source. If the source is 0, sets ZF; Intel’s manual leaves the destination undefined, AMD’s says it is not changed. With an F3 prefix, on processors that have BMI1, the same bytes are tzcnt. | 80386 (Intel 80386, 1985) |
bsr | r16/32/64, r/m16/32/64 | 0F BD /r | Bit scan reverse: writes the index of the highest set bit, with ZF as bsf. With F3, on processors that have LZCNT, it is lzcnt. | 80386 (Intel 80386, 1985) |
SETcc
SETcc writes 1 to a byte if the condition holds, and 0 otherwise. The conditions are those of the condition code table; the ModRM reg field is not used. The EVEX forms of SETcc and SETZUcc that APX adds are on the Data transfer page.
| Instruction | Forms | Encoding | What it does | Set |
|---|---|---|---|---|
seto | r/m8 | 0F 90 | Sets the byte if OF = 1. | 80386 (Intel 80386, 1985) |
setno | r/m8 | 0F 91 | Sets the byte if OF = 0. | 80386 (Intel 80386, 1985) |
setb | r/m8 | 0F 92 | Sets the byte if CF = 1 (below). | 80386 (Intel 80386, 1985) |
setae | r/m8 | 0F 93 | Sets the byte if CF = 0 (above or equal). | 80386 (Intel 80386, 1985) |
sete | r/m8 | 0F 94 | Sets the byte if ZF = 1 (equal). | 80386 (Intel 80386, 1985) |
setne | r/m8 | 0F 95 | Sets the byte if ZF = 0 (not equal). | 80386 (Intel 80386, 1985) |
setbe | r/m8 | 0F 96 | Sets the byte if CF = 1 or ZF = 1. | 80386 (Intel 80386, 1985) |
seta | r/m8 | 0F 97 | Sets the byte if CF = 0 and ZF = 0 (above). | 80386 (Intel 80386, 1985) |
sets | r/m8 | 0F 98 | Sets the byte if SF = 1. | 80386 (Intel 80386, 1985) |
setns | r/m8 | 0F 99 | Sets the byte if SF = 0. | 80386 (Intel 80386, 1985) |
setp | r/m8 | 0F 9A | Sets the byte if PF = 1. | 80386 (Intel 80386, 1985) |
setnp | r/m8 | 0F 9B | Sets the byte if PF = 0. | 80386 (Intel 80386, 1985) |
setl | r/m8 | 0F 9C | Sets the byte if SF ≠ OF (less). | 80386 (Intel 80386, 1985) |
setge | r/m8 | 0F 9D | Sets the byte if SF = OF. | 80386 (Intel 80386, 1985) |
setle | r/m8 | 0F 9E | Sets the byte if ZF = 1 or SF ≠ OF. | 80386 (Intel 80386, 1985) |
setg | r/m8 | 0F 9F | Sets the byte if ZF = 0 and SF = OF (greater). | 80386 (Intel 80386, 1985) |
Notes
- VEX forms. With a VEX prefix, the 0F 9x opcodes are not SETcc but
the AVX-512 mask moves and tests (
kmovw,kortestw…), on the AVX-512 mask registers page. - LOCK may be used with AND, OR, XOR, NOT, BTS, BTR and BTC when the destination is memory. On TEST, BT, the shifts or with a register destination it raises #UD.
- APX. In EVEX map 4, ND = 1 gives a new destination register in
EVEX.vvvv and NF = 1 leaves the flags alone (
{nf}). See APX’s EVEX fields. - Shift counts are shown unsigned, as LLVM shows them.
Links
Reference
- Intel 64 and IA-32 Architectures Software Developer’s Manuals – Intel’s manuals; volume 2 describes each instruction
- AMD64 Architecture Programmer’s Manual, Volume 3 – AMD’s reference to the general-purpose and system instructions
- Intel Advanced Performance Extensions (Intel APX) – Intel’s introduction to APX, with a link to its architecture specification
- x86 and amd64 instruction reference – Félix Cloutier’s web copy of the instruction pages of Intel’s manual