8086 Instruction Set

MOV, PUSH, POP, IN, OUT, arithmetic.

Darshan N
Updated: 19 March 2026
4 min read

The 8086 instruction set is a rich collection of operations grouped into data transfer, arithmetic, logical, string, control transfer, and processor control categories. Mastering the key instructions, their operand types, and their effect on flags is the foundation for writing 8086 assembly programs and for solving GATE questions on instruction execution.

8086 Instruction Set: Major GroupsInstruction SetData TransferArithmeticLogicalString OpsControl TransferProcessor CtrlMOV, PUSHPOP, IN, OUTXCHG, LEAADD, SUBMUL, DIVINC, DECAND, ORXOR, NOTCMP, TESTMOVSB/WREP, SCASCMPS, LODSJMP, CALLRET, LOOPJcc (conditional)CLC, STCCLI, STINOP, HLTMOV cannot move memory to memory directly. PUSH/POP always operate on 16-bit words in 8086.PUSH / POP Stack OperationPUSH AX: SP = SP - 2; [SS:SP] = AXPOP BX: BX = [SS:SP]; SP = SP + 2Stack grows downward (toward lower addresses)SP always points to top (last pushed word)IN / OUT Port InstructionsIN AL, DX: read byte from port in DXOUT DX, AL: write AL to port in DXFixed port: IN AL, 30H (port address in instruction)Variable port: use DX for ports > FFH
Figure 1: 8086 instruction set major groups with key instructions and important behavioral notes

Data Transfer Instructions

The MOV instruction is the most commonly used instruction in 8086 assembly. It copies data from a source operand to a destination operand. MOV cannot directly move data from one memory location to another in a single instruction; an intermediate register must be used. MOV also cannot move an immediate value directly into a segment register.

The PUSH instruction decrements SP by 2 and then stores a 16-bit word at the new stack top (SS:SP). The POP instruction reads the word from SS:SP and then increments SP by 2. Both instructions always operate on 16-bit (word) quantities in the 8086. The stack grows downward in memory.

The IN and OUT instructions handle I/O port communication. IN reads a byte or word from an I/O port into the accumulator (AL or AX). OUT writes from the accumulator to a port. For ports with addresses up to FFH, a fixed 8-bit port address can be embedded in the instruction. For higher port addresses, the port address must be loaded into DX first, then IN AL, DX or OUT DX, AL is used.

Arithmetic Instructions

The ADD and SUB instructions perform unsigned and signed addition and subtraction. Both update CF, SF, ZF, PF, AF, and OF. The ADC (Add with Carry) and SBB (Subtract with Borrow) instructions include the carry flag in the operation, making 32-bit or multi-precision arithmetic possible using two consecutive 16-bit operations.

The MUL instruction performs unsigned multiplication. For an 8-bit multiply (MUL BL), it uses AL as the implicit source and stores the 16-bit result in AX. For a 16-bit multiply (MUL BX), it uses AX and stores the 32-bit result in DX:AX. The IMUL instruction is the signed equivalent. DIV and IDIV perform unsigned and signed division respectively.

Logical and Bit Instructions

The AND, OR, and XOR instructions perform bitwise logical operations and update SF, ZF, PF while always clearing CF and OF. TEST performs AND without storing the result, only updating flags, and is used to check specific bits. CMP performs subtraction without storing the result, only updating flags for use by conditional jumps.

Control Transfer Instructions

Unconditional jumps use JMP, which can be short (8-bit displacement), near (16-bit, same segment), or far (different segment). CALL pushes the return address (CS:IP for far call, IP only for near call) onto the stack and jumps to the subroutine. RET pops the saved IP (and CS for far return) to resume execution after the call.

The LOOP instruction decrements CX and jumps to the target label if CX is not zero. It is a compact way to implement counted loops without a separate DEC and JNZ pair. Conditional jumps like JZ, JNZ, JC, JNC, JA, JB, JG, JL each test specific flag combinations. Signed comparisons use JG/JL (based on SF, OF); unsigned comparisons use JA/JB (based on CF).

Numerical Example

MUL is an important instruction with implicit operands. For 16-bit multiplication, the product is 32 bits wide. The lower 16 bits go to AX and the upper 16 bits go to DX. This must be accounted for when reading multiplication results.

Example
Given:
AX = 0300H (768 decimal)
BX = 0020H (32 decimal)
Instruction: MUL BX

Why this formula applies:
16-bit unsigned multiply: AX x BX, result in DX:AX (32-bit product)

Formula:
Product = AX x BX
High 16 bits → DX
Low 16 bits → AX

Substitution:
Product = 0300H x 0020H = 6000H

Calculation:
0300H x 0020H = 768 x 32 = 24,576 decimal = 6000H
6000H fits in 16 bits: DX = 0000H, AX = 6000H

Final Answer: DX = 0000H, AX = 6000H. CF = 0, OF = 0 (since DX = 0, no overflow).
Exam Tip: MOV cannot transfer memory to memory. MUL result goes to DX:AX (16-bit operand) or AX (8-bit operand). CMP and TEST only affect flags, not data. LOOP uses CX; it checks CX after decrement, so CX=0 on entry loops 65536 times. JA/JB are for unsigned; JG/JL are for signed comparisons.

Mechanism: Instruction Execution Flow

Key Instruction Behaviors: MOV, PUSH/POP, MUL, IN/OUTMOV RulesAllowed: Reg to Reg, Mem to Reg, Reg to MemAllowed: Imm to Reg, Imm to MemNot Allowed: Mem to Mem directlyNot Allowed: Imm to Segment RegisterNot Allowed: CS as destinationMOV CS, AX is invalid (CS is read-only)PUSH / POP StackStack Segment: SS:SP points to stack topPUSH: SP = SP - 2, write word at SPPOP: read word from SP, SP = SP + 2Stack grows toward lower addressesPUSHA/POPA push/pop all registersAlways 16-bit (word) operations in 8086MUL / IMUL8-bit: AL x src8 → AX16-bit: AX x src16 → DX:AXCF=OF=0 if upper half (AH or DX) = 0IMUL: signed; 2s complement resultDIV: AL = quotient, AH = remainder (8-bit)Divide overflow causes INT 0 exceptionIN / OUT I/O PortFixed: IN AL, n8 (port 0-255)Variable: IN AL, DX (port 0-65535)OUT n8, AL or OUT DX, ALIN/OUT AX for 16-bit port transferSeparate I/O address space (64K ports)M/IO pin distinguishes memory vs I/O cycle
Figure 2: Key instruction behaviors for MOV, PUSH/POP, MUL, and IN/OUT with allowed operands and flag effects
  • MOV cannot transfer data from memory to memory directly. Use register as intermediate.
  • PUSH and POP always deal with 16-bit words; SP decrements by 2 on PUSH, increments by 2 on POP.
  • MUL: 8-bit uses AL, result in AX. 16-bit uses AX, result in DX:AX. CF and OF are set if upper half is nonzero.
  • IN/OUT use fixed port (8-bit address in instruction) or variable port (address in DX).
  • CMP and TEST update flags only; ADD/SUB update both flags and the destination register.
  • LOOP decrements CX first, then checks if CX is zero. Falls through when CX becomes zero.

Quick Revision

  • MOV: no memory-to-memory, no immediate to segment register, CS cannot be destination.
  • PUSH: SP = SP - 2 first, then write. POP: read first, then SP = SP + 2.
  • MUL (8-bit): AL x src = AX. MUL (16-bit): AX x src = DX:AX.
  • DIV (16-bit / 8-bit): quotient in AL, remainder in AH. Divide by zero triggers INT 0.
  • LOOP decrements CX; jumps if CX is not zero. Starting with CX=0 causes 65536 iterations.
  • JA/JB use CF (unsigned); JG/JL use OF and SF (signed). Know which flags each conditional jump tests.
  • IN/OUT: use DX for port addresses greater than FFH. Accumulator (AL/AX) is always the source or destination.

Instruction Set Operations

Analyze data transfer and arithmetic instructions.

Question 1 of 3

Q1.Which instruction alters the Stack Pointer (SP) by subtracting 2 before storing data?