8086 Integer, Bit, String & I/O Instructions

The 8086 instruction set is easier to reason about as state transformations: data movement selects locations, arithmetic and logic define flag evidence, string operations advance implicit indexes, and port I/O crosses into a separate address space.

An opcode catalogue tells you what mnemonics exist but not how to reason about a program. A better model asks which state is read, which state is written, which flags become evidence for later control flow, and which operands are implicit. This exposes the shared mechanisms behind data movement, arithmetic, bit operations, strings, and port I/O.

Instruction effects, not mnemonic families #

instruction operation at explicit width defined architectural effects Explicit operands register · memory · immediate Implicit inputs CF · DF · SI/DI · CX · AX/DX External state memory · I/O port · bus effects Data result register or memory write Flag evidence defined · preserved · undefined Implicit outputs SI/DI · CX · SP · device state
An instruction may write data, flags, indexes, count state, or external device state; reading the mnemonic alone misses implicit effects.

For every instruction, build a small contract:

text
explicit inputs + implicit inputs
              ↓
        operation at width
              ↓
explicit outputs + implicit outputs + defined flags

Operand width is part of the operation. FFh + 01h as a byte and 00FFh + 0001h as a word produce different zero/carry evidence even though the visible hex operands look related.

Data movement changes location, not arithmetic evidence #

MOV, XCHG, PUSH, POP, LEA, IN, and OUT move or derive values. Ordinary MOV and LEA do not update arithmetic status flags.

Important constraints include:

  • ordinary MOV does not encode a general memory-to-memory copy;
  • LEA writes the effective offset, not the contents at that address;
  • XCHG exchanges two operands and at most one may be memory;
  • stack transfers are word-sized on the 8086 and implicitly use SS:SP;
  • port transfers implicitly use AL or AX for data.

A memory-to-memory copy is expressed through a register or a string instruction because the original execution and bus interfaces do not provide two arbitrary memory operands for ordinary ALU/data-transfer instructions.

Arithmetic: one bit pattern, two interpretations #

ADD, ADC, SUB, SBB, INC, DEC, NEG, CMP, multiply, and divide operate on fixed-width bit patterns. Signedness mainly changes which flag or instruction variant you use to interpret the result.

Byte operation Result CF OF ZF Interpretation
FFh + 01h 00h 1 0 1 unsigned overflow; signed -1 + 1 is valid
7Fh + 01h 80h 0 1 0 unsigned valid; signed positive overflow
00h - 01h FFh 1 0 0 unsigned borrow; signed 0 - 1 is valid
80h - 01h 7Fh 0 1 0 signed negative overflow

ADC and SBB include the incoming carry flag, which lets software chain arithmetic across multiple words. INC and DEC preserve CF; substituting them for ADD 1 or SUB 1 inside a multiword carry chain changes the contract.

CMP performs subtraction for flags and discards the numeric result. That makes a later conditional jump a consumer of evidence created by CMP. Unsigned conditions inspect carry and zero; signed conditions combine sign and overflow.

Logical, test, shift, and rotate operations #

AND, OR, and XOR write a Boolean result. TEST computes an AND for flags and discards the result, so it can inspect selected bits without modifying the operand.

Shifts move bits toward one end, putting the last shifted-out bit in CF. Arithmetic right shift (SAR) replicates the sign bit; logical right shift (SHR) inserts zero. Rotates reintroduce shifted-out bits at the other end, optionally through CF.

Flag definitions depend on the instruction and count. In particular, overflow is meaningful only for specified shift/rotate counts; code must not branch on an undefined flag value merely because an emulator or one processor happened to leave a repeatable bit.

Decimal-adjust instructions are representation adapters #

DAA, DAS, AAA, and AAS adjust binary arithmetic results for packed or unpacked binary-coded decimal conventions. They are not general decimal arithmetic. Their rules depend on AF, CF, and digit constraints, and later x86 modes restrict some of them.

They belong in the historical ISA because business data was often represented as decimal digits. New code usually uses explicit integer scaling or a decimal type whose range and rounding contract are visible.

String instructions are implicit state machines #

The 8086 string family operates on byte or word sequences with implicit registers:

Instruction Source Destination/result Typical repeat
MOVS DS:SI ES:DI REP
LODS DS:SI AL/AX sometimes REP
STOS AL/AX ES:DI REP
CMPS DS:SI compare with ES:DI, flags REPE/REPNE
SCAS AL/AX compare with ES:DI, flags REPE/REPNE

After each element, SI and/or DI move by one for a byte or two for a word. DF=0 increments; DF=1 decrements. A repeat prefix uses CX as the remaining element count. REPE/REPNE additionally stop according to ZF after compare/scan operations.

The destination segment is fixed to ES on the 8086. A segment override can change the source segment where permitted, not the destination rule.

Port I/O crosses a different namespace #

IN reads a port into AL or AX; OUT writes AL or AX to a port. The port is selected by an immediate eight-bit number or by DX, which exposes the full 16-bit port space.

Port I/O is not a memory dereference and does not use segment registers. A device register can have read side effects, write-triggered behavior, or timing requirements. Correct instruction encoding does not prove correct device protocol.

From flags to control flow #

Flags are short-lived dataflow. When a conditional branch is wrong, trace:

  1. which instruction most recently defined each tested flag;
  2. the operand width of that instruction;
  3. whether the intended comparison was signed or unsigned;
  4. whether an intervening instruction overwrote or left the flag undefined;
  5. whether the branch condition consumes the expected Boolean relation.

For example, after CMP AX,BX, “below” is an unsigned relation based on CF, while “less” is a signed relation based on SF and OF. The subtraction bits are identical; the interpretation differs.

Verification habits #

  • State every operand width explicitly while hand-tracing.
  • Record old flags only when the instruction consumes them (ADC, SBB, rotate-through-carry).
  • Record new flags only when the architecture defines them.
  • Expand string operations into one iteration plus their implicit index/count update.
  • Treat port reads/writes as calls into device state, not ordinary variables.
  • Compare assembler output with the encoding model before assuming the mnemonic selected the intended form.

Sources

  1. docsThe 8086 Family User's Manualpdfnotes
  2. docsIntel 64 and IA-32 Architectures Software Developer's Manualpdf

Searches titles, aliases, headings, summaries, and full text.↑↓ move ↵ open esc close