This is an HTML-ized version of the opcode map for the 8086 processor. It is based on the opcode map from Appendix A of Volume 2 of the Intel Architecture Software Developer's Manual. A plain-text version - easily parsable by software - is also available.

This map was constructed by taking a map for a more recent x86 processor and removing information irrelevant to the (much earlier) 8086 processor. I wanted as simple a map as possible, and, to that end, this map contains some lacunae:

In addition to the information that was removed, this map contains two known errors. These were added intentionally so that the results of disassembly based upon this map would mirror the output of DOS DEBUG:

To use the map, find the cell in the row labelled with the opcode's most significant 4 bits, and the column labelled with the opcode's least significant 4 bits. (The map is split in half; columns 0-7 appear in the first part, while columns 8-F appear in the second.) For instance, opcode 23 appears in the 3rd row, 4th column of the first part of the map (AND Gv, Ev). Opcode 4E appears in the 5th row, 7th column of the second part of the map (DEC SI).

Arguments are either a pair of letters - the first in upper case, the second in lower case - or a special symbol. An upper case/lower case pair can be interpreted by looking up the upper case letter in the "Argument Addressing Codes" table, and the lower case letter in the "Argument Operand Codes" table. Other special symbols can be looked up in the "Special Argument Codes" table.

Continuing the earlier example, opcode 23 resolves to an AND Gv, Ev instruction. Both arguments are upper case/lower case pairs. G represents a general-purpose register selected by the reg bits of a ModR/M byte following the opcode byte. E represents a memory location or general-purpose register selected by the mod and r/m bits of a ModR/M byte following the opcode byte. Both operands are of type "v", so both are WORDs. Opcode 23, therefore, takes the logical AND of a WORD from a 16-bit register or memory location with the WORD from a 16-bit register, and stores the result to the latter register. The particular register(s) and/or memory location involved can be determined by examining the ModR/M byte following the opcode, and consulting page 2-5 of the Instruction Set Reference.

Opcode 4E, on the other hand, resolves to a DEC SI instruction. The SI argument is not an upper case/lower case pair, so we check the special code table. SI turns out to represent (as one might expect) the 16-bit SI register, so opcode 4E simply decrements this register by 1. (Yes, with nearly 30 years hindsight, there probably shouldn't be an entire opcode devoted to this operation.)

The one remaining complexity involves "group" opcodes, such as 80. These opcodes perform different operations depending upon the value of the reg bits in the ModR/M byte following the opcode byte. For example, opcode 80 followed by a ModR/M byte with a reg of 4 is an AND Eb, Ib instruction, while that same opcode followed by a ModR/M byte with a reg of 7 is a CMP Eb, Ib instruction.

To disassemble "group" opcodes, consult the "Opcode Extensions" table for any entry in the opcode map with a mneumonic of the form GRP#. Find the entry in the row labelled with the mneumonic and the column labeled with the value of the reg field of the ModR/M byte following the opcode byte. Note that arguments may be specified in both the opcode map and the opcode extensions table (e.g. for opcode F6, reg 0); if this occurs, the entries in the extensions table take precedence. Normally, however, the arguments from the opcode map are used.

As far as I know, this opcode map is, modulo the lacunae and errata mentioned above, correct. I've used it to implement a full 8086 integer disassembler, the results of which agree with DOS DEBUG. However, if you see something that doesn't look right, please contact me. If you're interested in reading more about the disassembler, the following posts might be worth a look:

Opcode Map (Part 1)
0 1 2 3 4 5 6 7

0

ADD

Eb Gb

ADD

Ev Gv

ADD

Gb Eb

ADD

Gv Ev

ADD

AL Ib

ADD

AX Iv

PUSH

ES

POP

ES

1

ADC

Eb Gb

ADC

Ev Gv

ADC

Gb Eb

ADC

Gv Ev

ADC

AL Ib

ADC

AX Iv

PUSH

SS

POP

SS

2

AND

Eb Gb

AND

Ev Gv

AND

Gb Eb

AND

Gv Ev

AND

AL Ib

AND

AX Iv

ES:

DAA

3

XOR

Eb Gb

XOR

Ev Gv

XOR

Gb Eb

XOR

Gv Ev

XOR

AL Ib

XOR

AX Iv

SS:

AAA

4

INC

AX

INC

CX

INC

DX

INC

BX

INC

SP

INC

BP

INC

SI

INC

DI

5

PUSH

AX

PUSH

CX

PUSH

DX

PUSH

BX

PUSH

SP

PUSH

BP

PUSH

SI

PUSH

DI

6

7

JO

Jb

JNO

Jb

JB

Jb

JNB

Jb

JZ

Jb

JNZ

Jb

JBE

Jb

JA

Jb

8

GRP1

Eb Ib

GRP1

Ev Iv

GRP1

Eb Ib

GRP1

Ev Ib

TEST

Gb Eb

TEST

Gv Ev

XCHG

Gb Eb

XCHG

Gv Ev

9

NOP

XCHG

CX AX

XCHG

DX AX

XCHG

BX AX

XCHG

SP AX

XCHG

BP AX

XCHG

SI AX

XCHG

DI AX

A

MOV

AL Ob

MOV

AX Ov

MOV

Ob AL

MOV

Ov AX

MOVSB

MOVSW

CMPSB

CMPSW

B

MOV

AL Ib

MOV

CL Ib

MOV

DL Ib

MOV

BL Ib

MOV

AH Ib

MOV

CH Ib

MOV

DH Ib

MOV

BH Ib

C

RET

Iw

RET

LES

Gv Mp

LDS

Gv Mp

MOV

Eb Ib

MOV

Ev Iv

D

GRP2

Eb 1

GRP2

Ev 1

GRP2

Eb CL

GRP2

Ev CL

AAM

I0

AAD

I0

XLAT

E

LOOPNZ

Jb

LOOPZ

Jb

LOOP

Jb

JCXZ

Jb

IN

AL Ib

IN

AX Ib

OUT

Ib AL

OUT

Ib AX

F

LOCK

REPNZ

REPZ

HLT

CMC

GRP3a

Eb

GRP3b

Ev

Opcode Map (Part 2)
8 9 A B C D E F

0

OR

Eb Gb

OR

Ev Gv

OR

Gb Eb

OR

Gv Ev

OR

AL Ib

OR

AX Iv

PUSH

CS

1

SBB

Eb Gb

SBB

Ev Gv

SBB

Gb Eb

SBB

Gv Ev

SBB

AL Ib

SBB

AX Iv

PUSH

DS

POP

DS

2

SUB

Eb Gb

SUB

Ev Gv

SUB

Gb Eb

SUB

Gv Ev

SUB

AL Ib

SUB

AX Iv

CS:

DAS

3

CMP

Eb Gb

CMP

Ev Gv

CMP

Gb Eb

CMP

Gv Ev

CMP

AL Ib

CMP

AX Iv

DS:

AAS

4

DEC

AX

DEC

CX

DEC

DX

DEC

BX

DEC

SP

DEC

BP

DEC

SI

DEC

DI

5

POP

AX

POP

CX

POP

DX

POP

BX

POP

SP

POP

BP

POP

SI

POP

DI

6

7

JS

Jb

JNS

Jb

JPE

Jb

JPO

Jb

JL

Jb

JGE

Jb

JLE

Jb

JG

Jb

8

MOV

Eb Gb

MOV

Ev Gv

MOV

Gb Eb

MOV

Gv Ev

MOV

Ew Sw

LEA

Gv M

MOV

Sw Ew

POP

Ev

9

CBW

CWD

CALL

Ap

WAIT

PUSHF

POPF

SAHF

LAHF

A

TEST

AL Ib

TEST

AX Iv

STOSB

STOSW

LODSB

LODSW

SCASB

SCASW

B

MOV

AX Iv

MOV

CX Iv

MOV

DX Iv

MOV

BX Iv

MOV

SP Iv

MOV

BP Iv

MOV

SI Iv

MOV

DI Iv

C

RETF

Iw

RETF

INT

3

INT

Ib

INTO

IRET

D

E

CALL

Jv

JMP

Jv

JMP

Ap

JMP

Jb

IN

AL DX

IN

AX DX

OUT

DX AL

OUT

DX AX

F

CLC

STC

CLI

STI

CLD

STD

GRP4

Eb

GRP5

Ev

Opcode Map (Opcode Extensions)
0 1 2 3 4 5 6 7

GRP1

ADD

OR

ADC

SBB

AND

SUB

XOR

CMP

GRP2

ROL

ROR

RCL

RCR

SHL

SHR

SAR

GRP3a

TEST

Eb Ib

NOT

NEG

MUL

IMUL

DIV

IDIV

GRP3b

TEST

Ev Iv

NOT

NEG

MUL

IMUL

DIV

IDIV

GRP4

INC

DEC

GRP5

INC

DEC

CALL

CALL

Mp

JMP

JMP

Mp

PUSH

Argument Addressing Codes

A

Direct address. The instruction has no ModR/M byte; the address of the operand is encoded in the instruction. Applicable, e.g., to far JMP (opcode EA).

E

A ModR/M byte follows the opcode and specifies the operand. The operand is either a general-purpose register or a memory address. If it is a memory address, the address is computed from a segment register and any of the following values: a base register, an index register, a displacement.

G

The reg field of the ModR/M byte selects a general register.

I

Immediate data. The operand value is encoded in subsequent bytes of the instruction.

J

The instruction contains a relative offset to be added to the address of the subsequent instruction. Applicable, e.g., to short JMP (opcode EB), or LOOP.

M

The ModR/M byte may refer only to memory. Applicable, e.g., to LES and LDS.

O

The instruction has no ModR/M byte; the offset of the operand is encoded as a WORD in the instruction. Applicable, e.g., to certain MOVs (opcodes A0 through A3).

S

The reg field of the ModR/M byte selects a segment register.

Argument Operand Codes

0

Byte argument. Unusual in that arguments of this type are suppressed in ASM output when they have the default value of 10 (0xA). Applicable, e.g., to AAM and AAD.

b

Byte argument.

p

32-bit segment:offset pointer.

w

Word argument.

v

Word argument. (The 'v' code has a more complex meaning in later x86 opcode maps, from which this was derived, but here it's just a synonym for the 'w' code.)

Special Argument Codes

AL

8-bit register: The low byte of AX

CL

8-bit register: The low byte of CX

DL

8-bit register: The low byte of DX

BL

8-bit register: The low byte of BX

AH

8-bit register: The high byte of AX

CH

8-bit register: The high byte of CX

DH

8-bit register: The high byte of DX

BH

8-bit register: The high byte of BX

AX

16-bit register: The 'accumulator' register

CX

16-bit register: The 'counter' register

DX

16-bit register: The 'data' register

BX

16-bit register: The 'base' register

SP

16-bit register: The 'stack pointer' register

BP

16-bit register: The 'base pointer' register

SI

16-bit register: The 'source index' register

DI

16-bit register: The 'destination index' register

ES

16-bit register: The 'extra' segment register

CS

16-bit register: The 'code' segment register

SS

16-bit register: The 'stack' segment register

DS

16-bit register: The 'data' segment register

1

A constant argument of 1, implicit in the opcode, and not represented elsewhere in the instruction. This argument *is* displayed in assembly code.

3

A constant argument of 3, implicit in the opcode, and not represented elsewhere in the instruction. This argument *is* displayed in assembly code.

M

The ModR/M byte refers to a memory location, however the contents of that memory location are irrelevant; the address itself is the operand of the instruction. Applicable, e.g., to LEA.