How to read this page
Each instruction lists its forms: reg8 and reg16 are a register,
mem8 and mem16 a byte or word in memory, imm8 and
imm16 a value in the instruction. Encoding is the machine code:
/r is a ModRM byte with a register and a register or memory operand, /n a
ModRM byte whose register field is the number n (it extends the opcode), +rb and
+rw a register number (0 to 7) added to the opcode, ib and iw
an immediate byte or word (low byte first), cb and cw a relative offset,
cd a far pointer (offset, then segment). Size is the length in bytes,
with the ModRM byte but without a displacement. Cycles are clock cycles measured on
the emulator of this trainer. Two numbers such as 17/5 mean: 17 when the jump or loop is
taken, 5 when not; for a shift by CL they mean the time with CL = 2 and with CL = 0 (a shift takes 8 cycles
plus 4 for each bit shifted).
The cycles of a memory form are for [BX]. Other addressing modes cost more: see the table
of addressing modes below.
Registers
Flags (register FLAGS)
Addressing modes
Memory operands
The 8086 builds the offset of a memory operand from one of these eight forms, with an optional
displacement of 8 bits (−128 to 127) or 16 bits, or from a 16-bit address alone. The offset is
in the segment shown (DS, or SS when BP is used) unless the instruction has a segment override.
Only these combinations exist: one of BX or BP, one of SI or DI, in any pair, or one register alone.
[BP] has no form without a displacement: the assembler writes
[BP+0] with a zero byte.
Measured on the emulator for MOV CX,[mode], a 16-bit read from memory. The
Intel data book gives the same differences: 5 cycles of address for one register, 7 or 8 for a base plus an
index, 6 for an address alone, and 4 more for a displacement. The one difference is that this
emulator charges [BP+disp] one cycle more than the other registers with a displacement (it
adds 4 to the 6 cycles of an address alone), where the data book gives 9 for all of them.
Idioms
Short ways to do common jobs. Bytes and cycles are added up from the measured forms below; 17/5 means 17 when the jump is taken, 5 when not.
The machine
An 8088 with 1 MB of RAM, run as a DOS .COM program. CS, DS, ES and SS are
0100H, IP is 0100H (or the first byte of the program), SP is
FFFEH and IF is set. The program is loaded at 0100:0100. Offset 0 of the
segment holds INT 20H and the word at the top of the stack is 0, so a RET
from the program ends it, as under DOS. A segment is 64 KB; the address of
seg:off is seg × 16 + off, and it wraps at 1 MB.
A run ends at HLT, at the end of the program, at a breakpoint, when a watched byte
changes, at the cycle limit, at a divide error, or at an interrupt that nothing handles.
While the interrupt vector (the four bytes at 0000:n×4) is empty, these services are
built in. When the program sets a vector, the CPU runs the program's handler instead. Each costs the
cycles of the INT and of an IRET.
An INT with no service and no vector, the TF trap and INTO stop the run, and
the page says which interrupt it was. A zero byte sent to the console is not printed.
Notes on the cycles
- The cycles are those of the emulator: the 8088 timings of VirtualXT, with the penalty of the 8-bit
bus (4 more cycles for each word that goes to or from memory). They are close to the Intel data book,
but not always the same:
INC reg16takes 3 cycles here and 2 in the manual. - The numbers assume that the prefetch queue is full. A real 8088 also waits for its queue after a jump or a long instruction, so a real machine can be slower.
- The time of
MUL,IMUL,DIVandIDIVdepends on the operands; the number shown is for small values. - A conditional jump,
LOOPandJCXZshow two numbers: taken, then not taken. A shift by CL takes 8 cycles, plus 4 for each bit shifted; the two numbers are for CL = 2 and CL = 0. - With a
REPprefix a string instruction runs CX times, so the total is about CX times the cycles shown, plus a start-up cost.