Effective Address Calculation Practice
Master the EA formulas by tracing through real examples with every addressing mode
Open interactive version (quiz + challenge)Real-world analogy
What is it?
Effective Address calculation is the process of computing the offset within a segment where data resides. Each addressing mode has a formula combining base registers (BX/BP), index registers (SI/DI), and displacements. The physical address is always Segment × 10h + EA. Default segment rules determine which segment register is used unless explicitly overridden.
Real-world relevance
Compilers spend significant effort choosing the optimal addressing mode for each memory access. A good compiler minimizes the complexity of addressing modes to reduce instruction size and execution time. When you read disassembled code in tools like IDA Pro, objdump, or x64dbg, understanding EA calculation is essential for tracing how the program accesses memory — especially when analyzing malware or debugging crashes.
Key points
- EA Formula Review — Effective Address (EA) is the offset within a segment. Physical Address (PA) = Segment × 10h + EA. Each addressing mode has a different EA formula. The segment register is chosen by default rules unless overridden.
- Default Segment Rules — The 8086 has default segment assignments: any access using BX, SI, DI, or a displacement defaults to DS. Any access using BP defaults to SS. Instruction fetches use CS. String destinations (DI in STOSB/MOVSB) use ES. These can be overridden.
- Trace: Direct Addressing — Given DS=1000h, instruction MOV AX,[5000h]: EA = 5000h (displacement in instruction). PA = 1000h × 10h + 5000h = 10000h + 5000h = 15000h. CPU reads the word at physical address 15000h into AX.
- Trace: Register Indirect — Given DS=2000h, BX=0300h, instruction MOV CL,[BX]: EA = BX = 0300h. PA = 2000h × 10h + 0300h = 20000h + 0300h = 20300h. CPU reads the byte at physical address 20300h into CL.
- Trace: Based Addressing with BP — Given SS=3000h, BP=0100h, instruction MOV AX,[BP+08h]: EA = BP + 08h = 0100h + 08h = 0108h. Default segment is SS (BP used). PA = 3000h × 10h + 0108h = 30000h + 0108h = 30108h.
- Trace: Indexed Addressing — Given DS=1500h, SI=0040h, instruction MOV BL,[SI+2000h]: EA = SI + 2000h = 0040h + 2000h = 2040h. PA = 1500h × 10h + 2040h = 15000h + 2040h = 17040h.
- Trace: Based-Indexed with Displacement — Given DS=1000h, BX=0200h, DI=0010h, instruction MOV AX,[BX+DI+50h]: EA = BX + DI + 50h = 0200h + 0010h + 50h = 0260h. PA = 1000h × 10h + 0260h = 10000h + 0260h = 10260h.
- Trace: Segment Override — Given DS=1000h, ES=4000h, BX=0100h, instruction MOV AX,ES:[BX]: EA = BX = 0100h. Segment override forces ES instead of DS. PA = 4000h × 10h + 0100h = 40000h + 0100h = 40100h.
- EA Calculation Clock Cycles — More complex addressing modes take more clock cycles to compute the EA. Register is 0 extra. Direct is 6 clocks. Register indirect is 5. Based/indexed is 5+displacement. Based-indexed is 7-8. Based-indexed+displacement is 11-12.
Code example
; Complete EA practice worksheet
; Given: DS=1000h, SS=2000h, ES=3000h
; BX=0100h, BP=0200h, SI=0010h, DI=0020h
; Problem 1: MOV AX, [BX]
; EA = 0100h
; Seg = DS (BX -> DS)
; PA = 10000h + 0100h = 10100h
; Problem 2: MOV AX, [BP+06h]
; EA = 0200h + 06h = 0206h
; Seg = SS (BP -> SS)
; PA = 20000h + 0206h = 20206h
; Problem 3: MOV AX, [BX+SI]
; EA = 0100h + 0010h = 0110h
; Seg = DS (BX present -> DS)
; PA = 10000h + 0110h = 10110h
; Problem 4: MOV AX, [BP+DI+100h]
; EA = 0200h + 0020h + 0100h = 0320h
; Seg = SS (BP present -> SS)
; PA = 20000h + 0320h = 20320h
; Problem 5: MOV AX, ES:[SI+50h]
; EA = 0010h + 0050h = 0060h
; Seg = ES (override!)
; PA = 30000h + 0060h = 30060h
; Problem 6: MOV AX, [1234h]
; EA = 1234h
; Seg = DS (direct -> DS)
; PA = 10000h + 1234h = 11234hLine-by-line walkthrough
- 1. Problem 1: MOV AX,[BX] — register indirect. EA = BX = 0100h. BX defaults to DS. PA = 1000h×10h + 0100h = 10100h.
- 2. Problem 2: MOV AX,[BP+06h] — based addressing with BP. EA = 0200h + 06h = 0206h. BP defaults to SS. PA = 2000h×10h + 0206h = 20206h.
- 3. Problem 3: MOV AX,[BX+SI] — based-indexed. EA = 0100h + 0010h = 0110h. BX is present, so DS is default. PA = 10110h.
- 4. Problem 4: MOV AX,[BP+DI+100h] — based-indexed with displacement. EA = 0200h + 0020h + 0100h = 0320h. BP is present, so SS is default. PA = 20320h.
- 5. Problem 5: MOV AX,ES:[SI+50h] — indexed with segment override. EA = 0010h + 0050h = 0060h. Override forces ES instead of default DS. PA = 30060h.
- 6. Problem 6: MOV AX,[1234h] — direct addressing. EA = 1234h. No register, so DS is default. PA = 10000h + 1234h = 11234h.
- 7. Key insight: the EA formula depends only on registers and displacement. The segment adds a separate 'base' that shifts the entire access to a different 64 KB window in the 1 MB space.
- 8. Segment overrides cost 1 extra byte in the instruction encoding but can access any segment — essential when data spans multiple segments.
Spot the bug
; Given: DS = 1000h, SS = 2000h, BP = 0050h
; Goal: Read a local variable at stack offset [BP+04h]
; Then store it in a global variable at DS:3000h
;
MOV AX, [BP+04h] ; Read stack variable
MOV [BP+04h], AX ; Store to global at 3000h ???
;
; Programmer thinks both access the same location.
; But something is wrong with the second instruction.Need a hint?
Show answer
Explain like I'm 5
Fun fact
Hands-on challenge
More resources
- 8086 Address Calculation Examples (GeeksforGeeks)
- EA Calculation Step by Step (YouTube)
- 8086 Addressing Modes Practice Problems (TutorialsPoint)
- ModR/M Byte Encoding (OSDev Wiki)