8086 Addressing Modes
Master all the addressing modes in 8086 microprocessor with detailed explanations, examples, and practical applications.
Understanding Addressing Modes - Fundamentals
Addressing modes are fundamental concepts in computer architecture that specify how the processor locates and accesses operands (data) for instructions. In the 8086 microprocessor, addressing modes provide flexibility in data access patterns, enabling efficient programming and memory utilization.
What are Addressing Modes?
An addressing mode defines the method by which the processor determines the effective address of an operand. The choice of addressing mode affects:
- Instruction Length: Number of bytes required for the instruction
- Execution Time: Cycles needed to calculate effective address
- Memory Usage: Efficiency of memory access patterns
- Programming Flexibility: Ease of implementing data structures
8086 Addressing Mode Classification
The 8086 microprocessor supports nine distinct addressing modes, which can be categorized into three main groups:
Addressing Mode Selection Criteria
The choice of addressing mode depends on several factors:
- Data Location: Where the operand is stored (register, memory, immediate)
- Data Structure Type: Arrays, records, stacks, etc.
- Programming Convenience: Ease of coding and maintenance
- Performance Requirements: Speed vs. flexibility trade-offs
- Memory Constraints: Code size and memory usage considerations
Effective Address Calculation
Before examining individual modes, it's important to understand how the 8086 calculates effective addresses:
1. Immediate Addressing Mode
In immediate addressing, the operand (data) is part of the instruction itself. The data follows the opcode directly.
Syntax and Examples:
MOV AX, 1234H ; Load immediate value 1234H into AX
MOV BL, 25H ; Load immediate value 25H into BL
ADD AX, 100H ; Add immediate value 100H to AX
CMP BX, 0 ; Compare BX with immediate value 0
Characteristics:
- Fast Execution: No memory access required for operand
- Larger Instruction Size: Data is embedded in instruction
- Limited to Constants: Cannot modify the immediate value during execution
Memory Representation:
Instruction: MOV AX, 1234H
Memory: [B8] [34] [12] ; B8 = opcode, 34 12 = data (little endian)
2. Register Addressing Mode
Both source and destination operands are processor registers. This is the fastest addressing mode.
Examples:
MOV AX, BX ; Copy contents of BX to AX
ADD AX, CX ; Add CX to AX, store result in AX
SUB DX, BX ; Subtract BX from DX
XOR AX, AX ; Clear AX register (AX = AX XOR AX = 0)
Register Combinations:
- 16-bit Registers: AX, BX, CX, DX, SI, DI, SP, BP
- 8-bit Registers: AH, AL, BH, BL, CH, CL, DH, DL
- Segment Registers: CS, DS, SS, ES
Execution Time:
Register addressing mode has the shortest execution time since no memory access is required.
3. Direct Addressing Mode
The operand's effective address is specified directly in the instruction. The processor accesses memory using this address.
Examples:
MOV AX, [1234H] ; Load data from memory address 1234H into AX
MOV [5000H], BX ; Store BX contents to memory address 5000H
ADD AX, [2000H] ; Add data at memory address 2000H to AX
CMP [3000H], 100H; Compare data at 3000H with immediate value 100H
Physical Address Calculation:
For instruction: MOV AX, [1234H]
If DS = 2000H:
Physical Address = (DS × 16) + Offset
= (2000H × 16) + 1234H
= 20000H + 1234H = 21234H
Advantages and Disadvantages:
- ✓ Simple: Direct memory access
- ✓ Clear: Address is explicitly stated
- ✗ Fixed: Address cannot be changed during execution
- ✗ Slower: Requires memory access
4. Register Indirect Addressing Mode
The address of the operand is stored in a register. The register acts as a pointer to the memory location.
Allowed Registers:
Only BX, SI, DI, and BP can be used for indirect addressing.
Examples:
MOV AX, [BX] ; Load data from memory address stored in BX
MOV [SI], CX ; Store CX to memory address stored in SI
ADD AX, [DI] ; Add data at address stored in DI to AX
MOV [BP], DX ; Store DX to memory address stored in BP
Practical Example:
; Array access example
MOV BX, 2000H ; BX points to start of array
MOV AX, [BX] ; Load first element
INC BX ; Move to next element
INC BX ; (16-bit data, so increment by 2)
MOV CX, [BX] ; Load second element
Segment Override:
- BX, SI, DI: Use DS by default
- BP: Uses SS by default
- Override: Can specify different segment (e.g., ES:[BX])
5. Based Addressing Mode
Combines a base register (BX or BP) with a displacement (offset) to calculate the effective address.
Formula:
Effective Address = Base Register + Displacement
Examples:
MOV AX, [BX+10H] ; EA = BX + 10H
MOV [BP+5], CX ; EA = BP + 5
ADD AX, [BX+20H] ; EA = BX + 20H
MOV DX, [BP-4] ; EA = BP - 4 (negative displacement)
Use Cases:
- Structure Access: BX points to structure, displacement selects field
- Local Variables: BP points to stack frame, displacement selects variable
- Array Indexing: BX points to array base, displacement is element offset
Structure Access Example:
; Student record structure
; Name: offset 0, Age: offset 20, Grade: offset 22
MOV BX, 3000H ; Point to student record
MOV AX, [BX+20] ; Load age field
MOV CX, [BX+22] ; Load grade field
6. Indexed Addressing Mode
Uses an index register (SI or DI) with a displacement to calculate the effective address.
Formula:
Effective Address = Index Register + Displacement
Examples:
MOV AX, [SI+100H]; EA = SI + 100H
MOV [DI+50H], BX ; EA = DI + 50H
ADD CX, [SI+10] ; EA = SI + 10
MOV DX, [DI-2] ; EA = DI - 2
Array Processing Example:
; Process array of 16-bit integers
MOV SI, 0 ; Initialize index
MOV CX, 5 ; Array size
LOOP_START:
MOV AX, [SI+2000H] ; Load array element
ADD AX, 10H ; Process element
MOV [SI+3000H], AX ; Store to result array
ADD SI, 2 ; Move to next element (16-bit)
LOOP LOOP_START
Comparison with Based Addressing:
- Based: Typically used for structures and stack variables
- Indexed: Typically used for arrays and sequential data
- Performance: Both have similar execution time
7. Based Indexed Addressing Mode
Combines a base register, an index register, and optionally a displacement to provide maximum addressing flexibility.
Formula:
Effective Address = Base + Index + Displacement
Examples:
MOV AX, [BX+SI] ; EA = BX + SI
MOV [BP+DI+10H], CX ; EA = BP + DI + 10H
ADD AX, [BX+SI+5] ; EA = BX + SI + 5
MOV DX, [BP+DI-8] ; EA = BP + DI - 8
Two-Dimensional Array Example:
; Access element in 2D array: array[row][column]
; Array base address: 4000H
; Each row has 10 elements (20 bytes for 16-bit integers)
MOV BX, 4000H ; Base address of array
MOV AX, 3 ; Row number
MOV CX, 20 ; Bytes per row
MUL CX ; AX = row * bytes_per_row
MOV SI, AX ; SI = row offset
MOV DI, 8 ; Column offset (4 * 2 bytes)
MOV AX, [BX+SI+DI] ; Load array[3][4]
Valid Combinations:
- BX + SI + displacement
- BX + DI + displacement
- BP + SI + displacement
- BP + DI + displacement
8. String Addressing Mode
Special addressing mode used with string instructions. Automatically uses SI for source and DI for destination.
String Instructions:
MOVSB ; Move byte from DS:SI to ES:DI
MOVSW ; Move word from DS:SI to ES:DI
CMPSB ; Compare bytes at DS:SI and ES:DI
CMPSW ; Compare words at DS:SI and ES:DI
SCASB ; Scan byte at ES:DI
LODSB ; Load byte from DS:SI to AL
STOSB ; Store AL to ES:DI
Direction Control:
- CLD: Clear direction flag - auto increment SI/DI
- STD: Set direction flag - auto decrement SI/DI
String Copy Example:
; Copy 100 bytes from source to destination
MOV SI, 2000H ; Source address
MOV DI, 3000H ; Destination address
MOV CX, 100 ; Number of bytes
CLD ; Forward direction
REP MOVSB ; Repeat move string byte
9. I/O Port Addressing
Special addressing mode for input/output operations using IN and OUT instructions.
Direct Port Addressing:
IN AL, 60H ; Read byte from port 60H to AL
OUT 61H, AL ; Write AL to port 61H
IN AX, 64H ; Read word from port 64H to AX
OUT 65H, AX ; Write AX to port 65H
Indirect Port Addressing:
MOV DX, 378H ; Port address in DX
IN AL, DX ; Read from port specified by DX
OUT DX, AL ; Write to port specified by DX
Port Address Range:
- Direct: 8-bit port address (0-255)
- Indirect: 16-bit port address in DX (0-65535)
Numerical Problems
Problem 1: Effective Address Calculation
Question: Calculate the effective address for instruction MOV AX, [BX+SI+10H] where BX = 2000H, SI = 0500H, DS = 1000H.
Solution:
Given: BX = 2000H, SI = 0500H, Displacement = 10H, DS = 1000H
Effective Address = BX + SI + Displacement
= 2000H + 0500H + 10H
= 2510H
Physical Address = (DS × 16) + Effective Address
= (1000H × 16) + 2510H
= 10000H + 2510H
= 12510H
Answer: Effective Address = 2510H, Physical Address = 12510H
Problem 2: Array Element Access
Question: An array of 16-bit integers starts at address 3000H. Write instruction to access the 5th element using indexed addressing.
Solution:
Array starts at 3000H
Each element is 16-bit (2 bytes)
5th element offset = (5-1) × 2 = 8 bytes = 8H
Method 1: Using displacement
MOV AX, [3008H] ; Direct addressing
Method 2: Using indexed addressing
MOV SI, 8H ; Index for 5th element
MOV AX, [SI+3000H] ; Indexed addressing
Answer: MOV AX, [SI+3000H] where SI = 8H
Problem 3: Memory Access Time Comparison
Question: Rank the following addressing modes by execution speed (fastest to slowest):
Given Instructions:
1. MOV AX, BX (Register)
2. MOV AX, 1234H (Immediate)
3. MOV AX, [1234H] (Direct)
4. MOV AX, [BX+SI+10H] (Based Indexed)
Solution:
Ranking by speed (fastest to slowest):
1. MOV AX, BX - Register addressing (fastest)
No memory access required
2. MOV AX, 1234H - Immediate addressing
Data is part of instruction
3. MOV AX, [1234H] - Direct addressing
One memory access for data
4. MOV AX, [BX+SI+10H] - Based indexed addressing (slowest)
Address calculation + memory access
Answer: Register > Immediate > Direct > Based Indexed
Advanced Numerical Problems
Problem 1: Complex Address Calculation
Question: If DS = 2000H, BX = 1200H, SI = 0300H, and displacement = 50H, calculate the physical address for instruction MOV AX, [BX+SI+50H].
Solution:
Given:
DS = 2000H
BX = 1200H
SI = 0300H
Displacement = 50H
Step 1: Calculate Effective Address (EA)
EA = BX + SI + Displacement
EA = 1200H + 0300H + 50H = 1550H
Step 2: Calculate Physical Address
Physical Address = (DS × 16) + EA
Physical Address = (2000H × 16) + 1550H
Physical Address = 20000H + 1550H = 21550H
Answer: Physical Address = 21550H
Problem 2: Array Element Access
Question: An array of 16-bit integers starts at offset 1000H in data segment. Calculate the effective address to access the 5th element (index 4) using indexed addressing.
Solution:
Given:
Array base offset = 1000H
Element size = 2 bytes (16-bit integer)
Element index = 4 (5th element, 0-based indexing)
Method 1: Using displacement
EA = Base + (Index × Element_Size)
EA = 1000H + (4 × 2) = 1000H + 8 = 1008H
Instruction: MOV AX, [1008H]
Method 2: Using indexed addressing
SI = Index × Element_Size = 4 × 2 = 8
Instruction: MOV AX, [SI+1000H]
EA = SI + 1000H = 8 + 1000H = 1008H
Answer: Effective Address = 1008H
Problem 3: Structure Field Access
Question: A student record structure has: Name (20 bytes), Age (2 bytes), Grade (2 bytes). If the structure starts at DS:2000H, calculate addresses for each field of the 3rd record.
Solution:
Structure Layout:
Name: 20 bytes (offset 0-19)
Age: 2 bytes (offset 20-21)
Grade: 2 bytes (offset 22-23)
Total structure size = 24 bytes
For 3rd record (index 2):
Base address of 3rd record = 2000H + (2 × 24) = 2000H + 48 = 2030H
Field addresses:
Name field: 2030H + 0 = 2030H
Age field: 2030H + 20 = 2030H + 14H = 2044H
Grade field: 2030H + 22 = 2030H + 16H = 2046H
Assembly instructions:
LEA BX, [2030H] ; Point to 3rd record
MOV AX, [BX+14H] ; Load age
MOV CX, [BX+16H] ; Load grade
Answer: Name=2030H, Age=2044H, Grade=2046H
Problem 4: Memory Efficiency Analysis
Question: Compare memory usage for accessing 100 array elements using different addressing modes.
Solution:
Method 1: Direct addressing (100 different instructions)
MOV AX, [2000H] ; 3 bytes per instruction
MOV AX, [2002H] ; 3 bytes per instruction
...
Total: 100 × 3 = 300 bytes
Method 2: Indexed addressing (loop)
MOV SI, 0 ; 3 bytes
LOOP_START:
MOV AX, [SI+2000H] ; 4 bytes
ADD SI, 2 ; 3 bytes
CMP SI, 200 ; 4 bytes (100 elements × 2 bytes)
JB LOOP_START ; 2 bytes
Total: 3 + 4 + 3 + 4 + 2 = 16 bytes (plus loop overhead)
Memory saved = 300 - 16 = 284 bytes (94.7% reduction)
Answer: Indexed addressing saves 284 bytes (94.7% memory reduction)
Problem 5: Performance Calculation
Question: Calculate execution time difference between register and memory-based operations at 8MHz.
Solution:
Given: Clock frequency = 8MHz, Clock period = 125ns
Operation comparison for 1000 additions:
Method 1: Register-to-register
MOV CX, 1000 ; 4 cycles
ADD AX, BX ; 3 cycles × 1000 = 3000 cycles
Total: 4 + 3000 = 3004 cycles
Time = 3004 × 125ns = 375.5 μs
Method 2: Register-to-memory
MOV CX, 1000 ; 4 cycles
ADD AX, [SI] ; 9 cycles × 1000 = 9000 cycles
Total: 4 + 9000 = 9004 cycles
Time = 9004 × 125ns = 1125.5 μs
Performance difference:
Time saved = 1125.5 - 375.5 = 750 μs
Speedup = 1125.5 / 375.5 = 3.0×
Answer: Register operations are 3× faster, saving 750 μs
Problem 6: Segment Boundary Check
Question: Check if accessing a 1KB array starting at DS:F000H will cause segment overflow.
Solution:
Given:
Array start offset = F000H
Array size = 1KB = 1024 bytes = 400H
DS segment can address 0000H to FFFFH (64KB total)
Array end calculation:
Array end offset = F000H + 400H - 1 = F3FFH
Segment boundary check:
Maximum offset in segment = FFFFH
Array end offset = F3FFH
Since F3FFH < FFFFH, the array fits within the segment.
Available space after array = FFFFH - F3FFH = 0C00H = 3072 bytes
Answer: No segment overflow. Array fits with 3072 bytes remaining.
Problem 7: Instruction Length Analysis
Question: Calculate the total instruction length for different addressing mode examples.
Solution:
Instruction length analysis:
1. MOV AX, BX ; Register addressing
Opcode + ModR/M = 2 bytes
2. MOV AX, 1234H ; Immediate addressing
Opcode + Data = 3 bytes
3. MOV AX, [1234H] ; Direct addressing
Opcode + Address = 3 bytes
4. MOV AX, [BX] ; Register indirect
Opcode + ModR/M = 2 bytes
5. MOV AX, [BX+10H] ; Based addressing
Opcode + ModR/M + Disp = 3 bytes
6. MOV AX, [BX+SI+10H] ; Based indexed
Opcode + ModR/M + Disp = 4 bytes
Total program size = 2+3+3+2+3+4 = 17 bytes
Memory efficiency ranking (shortest to longest):
Register = Register Indirect (2 bytes)
Immediate = Direct = Based (3 bytes)
Based Indexed (4 bytes)
Answer: Total length = 17 bytes
Practical Programming Exercises
Exercise 1: Dynamic Array Access
Write code to access array elements using user input as index:
.DATA
ARRAY DW 10, 20, 30, 40, 50
INDEX DB ?
.CODE
; Assume INDEX contains desired element number (1-5)
MOV AL, INDEX ; Load index
DEC AL ; Convert to 0-based
MOV AH, 0 ; Clear high byte
SHL AX, 1 ; Multiply by 2 (word size)
MOV SI, AX ; Use as index
MOV BX, ARRAY[SI] ; Load array element
Exercise 2: String Character Access
Access individual characters in a string using indexed addressing:
.DATA
MESSAGE DB 'PROGRAMMING', 0
.CODE
MOV SI, 0 ; Start at first character
CHAR_LOOP:
MOV AL, MESSAGE[SI] ; Load character
CMP AL, 0 ; Check for null terminator
JE DONE
; Process character in AL
INC SI ; Move to next character
JMP CHAR_LOOP
DONE:
Exercise 3: 2D Array Access
Access elements in a 2D array (3×4 matrix):
.DATA
MATRIX DW 1,2,3,4, 5,6,7,8, 9,10,11,12 ; 3×4 matrix
ROWS EQU 3
COLS EQU 4
.CODE
; Access element at row=1, col=2 (0-based indexing)
MOV AX, 1 ; Row index
MOV BX, COLS ; Columns per row
MUL BX ; Row × Columns
ADD AX, 2 ; Add column index
SHL AX, 1 ; Word addressing
MOV SI, AX ; Use as index
MOV DX, MATRIX[SI] ; Load matrix element
Common Programming Mistakes
1. Incorrect Address Calculation
; WRONG: Forgetting word size
MOV SI, 5 ; Want 5th element
MOV AX, ARRAY[SI] ; Gets wrong element!
; CORRECT: Account for word size
MOV SI, 5 ; Element index
SHL SI, 1 ; Multiply by 2 for word size
MOV AX, ARRAY[SI] ; Gets correct element
2. Segment Register Confusion
; WRONG: Using wrong segment
MOV BP, 1000H
MOV AX, [BP] ; Uses SS segment, not DS!
; CORRECT: Explicit segment override
MOV BP, 1000H
MOV AX, DS:[BP] ; Explicitly use DS segment
3. Index Register Misuse
; WRONG: Using invalid registers for indirection
MOV AX, [CX] ; CX cannot be used for indirection!
; CORRECT: Use valid registers
MOV BX, CX ; Copy to valid register
MOV AX, [BX] ; Now use for indirection
Addressing Mode Summary
Understanding when to use each addressing mode is crucial for efficient 8086 programming.
Selection Guidelines:
- Performance Critical: Use register addressing when possible
- Constants: Use immediate addressing for fixed values
- Simple Variables: Use direct addressing for global variables
- Arrays: Use indexed addressing for sequential access
- Structures: Use based addressing for record fields
- Complex Data: Use based indexed for multi-dimensional arrays