Original 8086/8088 instruction set

In-
struc-
tion
MeaningNotesOpcode
AAAASCII adjust AL after additionused with unpacked binary-coded decimal0x37
AADASCII adjust AX before division8086/8088 datasheet documents only base 10 version of the AAD instruction (opcode 0xD5 0x0A), but any other base will work. Later Intel’s documentation has the generic form too. NEC V20 and V30 (and possibly other NEC V-series CPUs) always use base 10, and ignore the argument, causing a number of incompatibilities0xD5
AAMASCII adjust AX after multiplicationOnly base 10 version (Operand is 0xA) is documented, see notes for AAD0xD4
AASASCII adjust AL after subtraction0x3F
ADCAdd with carry(1) r += (r/m/imm+CF); (2) m += (r/imm+CF);0x10…0x15, 0x80…0x81/2, 0x83/2
ADDAdd(1) r += r/m/imm; (2) m += r/imm;0x00…0x05, 0x80/0…0x81/0, 0x83/0
ANDLogical AND(1) r &= r/m/imm; (2) m &= r/imm;0x20…0x25, 0x80…0x81/4, 0x83/4
CALLCall procedurepush eip; eip points to the instruction directly after the call0x9A, 0xE8, 0xFF/2, 0xFF/3
CBWConvert byte to wordAX = AL ; sign extended0x98
CLCClear carry flagCF = 0;0xF8
CLDClear direction flagDF = 0;0xFC
CLIClear interrupt flagIF = 0;0xFA
CMCComplement carry flagCF = !CF;0xF5
CMPCompare operands(1) r - r/m/imm; (2) m - r/imm;0x38…0x3D, 0x80…0x81/7, 0x83/7
CMPSBCompare bytes in memory. May be used with a REPE or REPNE prefix to test and repeat the instruction CX times.if (DF==0) *(byte*)SI++ – *(byte*)ES:DI++; else *(byte*)SI– – *(byte*)ES:DI–;0xA6
CMPSWCompare words. May be used with a REPE or REPNE prefix to test and repeat the instruction CX times.if (DF==0) *(word*)SI++ – *(word*)ES:DI++; else *(word*)SI– – *(word*)ES:DI–;0xA7
CWDConvert word to doubleword0x99
DAADecimal adjust AL after addition(used with packed binary-coded decimal)0x27
DASDecimal adjust AL after subtraction0x2F
DECDecrement by 10x48…0x4F, 0xFE/1, 0xFF/1
DIVUnsigned divide(1) AX = DX:AX / r/m; resulting DX = remainder (2) AL = AX / r/m; resulting AH = remainder0xF7/6, 0xF6/6
ESCUsed with floating-point unit0xD8..0xDF
HLTEnter halt state0xF4
IDIVSigned divide(1) AX = DX:AX / r/m; resulting DX = remainder (2) AL = AX / r/m; resulting AH = remainder0xF7/7, 0xF6/7
IMULSigned multiply in One-operand form(1) DX:AX = AX * r/m; (2) AX = AL * r/m0xF7/5, 0xF6/5
INInput from port(1) AL = port[imm]; (2) AL = port[DX]; (3) AX = port[imm]; (4) AX = port[DX];0xE4, 0xE5, 0xEC, 0xED
INCIncrement by 10x40…0x47, 0xFE/0, 0xFF/0
INTCall to interrupt0xCC, 0xCD
INTOCall to interrupt if overflow0xCE
IRETReturn from interrupt0xCF
JccJump if conditionJA, JAE, JB, JBE, JC (same as JB), JE, JG, JGE, JL, JLE, JNA (same as JBE), JNAE (same as JB), JNB (same as JAE), JNBE, JNC (same as JAE), JNE, JNG (same as JLE), JNGE (same as JL), JNL (same as JGE), JNLE (same as JG), JNO, JNP, JNS, JNZ (same as JNE), JO, JP, JPE (same as JP), JPO (same as JNP), JS, JZ (same as JE)[3]0x70…0x7F
JCXZJump if CX is zeroJECXZ for ECX instead of CX in 32 bit mode (same opcode).0xE3
JMPJump0xE9…0xEB, 0xFF/4, 0xFF/5
LAHFLoad FLAGS into AH register0x9F
LDSLoad DS:r with far pointerr = m; DS = 2 + m;0xC5
LEALoad Effective Address0x8D
LESLoad ES:r with far pointerr = m; ES = 2 + m;0xC4
LOCKAssert BUS LOCK# signal(for multiprocessing)0xF0
LODSBLoad string byte. May be used with a REP prefix to repeat the instruction CX times.if (DF==0) AL = *SI++; else AL = *SI--;0xAC
LODSWLoad string word. May be used with a REP prefix to repeat the instruction CX times.if (DF==0) AX = *SI++; else AX = *SI--;0xAD
LOOP/
LOOPx
Loop control(LOOPE, LOOPNE, LOOPNZ, LOOPZ) if (x && --CX) goto lbl;0xE0…0xE2
MOVMove(1) r = r/m/imm; (2) m = r/imm; (3) r/m = sreg; (4) sreg = r/m;0xA0…0xA3, 0x8C, 0x8E
MOVSBMove byte from string to string. May be used with a REP prefix to repeat the instruction CX times.if (DF==0) *(byte*)ES:DI++ = *(byte*)SI++; else *(byte*)ES:DI– = *(byte*)SI–; .0xA4
MOVSWMove word from string to string. May be used with a REP prefix to repeat the instruction CX times.if (DF==0) *(word*)ES:DI++ = *(word*)SI++; else *(word*)ES:DI– = *(word*)SI–;0xA5
MULUnsigned multiply(1) DX:AX = AX * r/m; (2) AX = AL * r/m;0xF7/4, 0xF6/4
NEGTwo’s complement negationr/m = 0 – r/m;0xF6/3…0xF7/3
NOPNo operationopcode equivalent to XCHG EAX, EAX0x90
NOTNegate the operand, logical NOTr/m ^= -1;0xF6/2…0xF7/2
ORLogical OR(1) r ∣= r/m/imm; (2) m ∣= r/imm;0x08…0x0D, 0x80…0x81/1, 0x83/1
OUTOutput to port(1) port[imm] = AL; (2) port[DX] = AL; (3) port[imm] = AX; (4) port[DX] = AX;0xE6, 0xE7, 0xEE, 0xEF
POPPop data from stackr/m/sreg = *SP++;0x07, 0x17, 0x1F, 0x58…0x5F, 0x8F/0
POPFPop FLAGS register from stackFLAGS = *SP++;0x9D
PUSHPush data onto stack*--SP = r/m/sreg;0x06, 0x0E, 0x16, 0x1E, 0x50…0x57, 0xFF/6
PUSHFPush FLAGS onto stack*--SP = FLAGS;0x9C
RCLRotate left (with carry)0xC0…0xC1/2 (186+), 0xD0…0xD3/2
RCRRotate right (with carry)0xC0…0xC1/3 (186+), 0xD0…0xD3/3
REPxxRepeat MOVS/STOS/CMPS/LODS/SCAS(REP, REPE, REPNE, REPNZ, REPZ)0xF2, 0xF3
RETReturn from procedureNot a real instruction. The assembler will translate these to a RETN or a RETF depending on the memory model of the target system.
RETFReturn from far procedure0xCA, 0xCB
RETNReturn from near procedure0xC2, 0xC3
ROLRotate left0xC0…0xC1/0 (186+), 0xD0…0xD3/0
RORRotate right0xC0…0xC1/1 (186+), 0xD0…0xD3/1
SAHFStore AH into FLAGS0x9E
SALShift Arithmetically left (signed shift left)(1) r/m <<= 1; (2) r/m <<= CL;0xC0…0xC1/4 (186+), 0xD0…0xD3/4
SARShift Arithmetically right (signed shift right)(1) (signed) r/m >>= 1; (2) (signed) r/m >>= CL;0xC0…0xC1/7 (186+), 0xD0…0xD3/7
SBBSubtraction with borrow(1) r -= (r/m/imm+CF); (2) m -= (r/imm+CF); alternative 1-byte encoding of SBB AL, AL is available via undocumented SALC instruction0x18…0x1D, 0x80…0x81/3, 0x83/3
SCASBCompare byte string. May be used with a REPE or REPNE prefix to test and repeat the instruction CX times.if (DF==0) AL - *ES:DI++; else AL - *ES:DI--;0xAE
SCASWCompare word string. May be used with a REPE or REPNE prefix to test and repeat the instruction CX times.if (DF==0) AX - *ES:DI++; else AX - *ES:DI--;0xAF
SHLShift left (unsigned shift left)Same opcode as SAL, since logical left shifts are equal to arithmetical left shifts.0xC0…0xC1/4 (186+), 0xD0…0xD3/4
SHRShift right (unsigned shift right)0xC0…0xC1/5 (186+), 0xD0…0xD3/5
STCSet carry flagCF = 1;0xF9
STDSet direction flagDF = 1;0xFD
STISet interrupt flagIF = 1;0xFB
STOSBStore byte in string. May be used with a REP prefix to repeat the instruction CX times.if (DF==0) *ES:DI++ = AL; else *ES:DI-- = AL;0xAA
STOSWStore word in string. May be used with a REP prefix to repeat the instruction CX times.if (DF==0) *ES:DI++ = AX; else *ES:DI-- = AX;0xAB
SUBSubtraction(1) r -= r/m/imm; (2) m -= r/imm;0x28…0x2D, 0x80…0x81/5, 0x83/5
TESTLogical compare (AND)(1) r & r/m/imm; (2) m & r/imm;0x84, 0x85, 0xA8, 0xA9, 0xF6/0, 0xF7/0
WAITWait until not busyWaits until BUSY# pin is inactive (used with floating-point unit)0x9B
XCHGExchange datar :=: r/m; A spinlock typically uses xchg as an atomic operation. (coma bug).0x86, 0x87, 0x91…0x97
XLATTable look-up translationbehaves like MOV AL, [BX+AL]0xD7
XORExclusive OR(1) r ^+= r/m/imm; (2) m ^= r/imm;0x30…0x35, 0x80…0x81/6, 0x83/6