An operand is a register, an immediate value in the instruction, or a memory location. For memory, the CPU computes a 16-bit offset, the effective address, from up to three parts: a base register (BX or BP), an index register (SI or DI) and a displacement, a constant stored in the instruction. Any one, two or all three can be used. The offset is then combined with a segment register to form the physical address.

ModeExampleAddress
DirectMOV AX, [N1]DS:N1
Register indirectMOV AL, [BX]DS:BX (also SI, DI)
BasedMOV AX, [BP+4]SS:BP+4
IndexedMOV AL, TABLE[SI]DS:TABLE+SI
Based indexedMOV AL, [BX+DI]DS:BX+DI
Based indexed + displacementMOV AL, [BP+SI+2]SS:BP+SI+2
Prints 9.
MOV AL, [NUMS] ; direct: 1
MOV BX, OFFSET NUMS
ADD AL, [BX+1] ; base + displacement: + 2
MOV SI, 2
ADD AL, [BX+SI] ; base + index: + 3
ADD AL, NUMS[SI+1] ; index + displacement: + 2
MOV DI, OFFSET NUMS
ADD AL, [DI] ; register indirect: + 1
ADD AL, '0' ; digit -> character
MOV DL, AL
MOV AH, 02h ; DOS: print DL
INT 21h
NUMS DB 1, 2, 3, 2

Default segments

An address that uses BP is in the stack segment SS; every other one is in DS. This fits the usual layout: BP points into a stack frame, the other registers point at data. A segment prefix such as ES: overrides the default for one operand. String instructions have fixed rules: the source is DS:SI and the destination ES:DI.

Writing them in MASM

TABLE[SI], [TABLE+SI] and [SI+TABLE] all mean the same thing, as do [BX][SI] and [BX+SI]. The displacement is stored as one signed byte when it fits in -128..127, otherwise as a word.

What does not exist

MOV AX, [BP] ; fine: encoded as [BP+0], segment SS
; MOV AX, [AX] ; no: only BX, BP, SI and DI address memory
; MOV AX, [BX+BP] ; no: two base registers
; MOV AX, [SI+DI] ; no: two index registers
; MOV AX, [BX+SI*2] ; no: scaling came with the 80386

An instruction has at most one memory operand. The offset is 16 bits and wraps around: [BX+SI] with a sum above FFFFh lands at the start of the segment, not beyond it.

Later CPUs

With 32-bit addressing on the 80386, any general register can be the base, any but ESP the index, and the index can be multiplied by 1, 2, 4 or 8: [EBX+ESI*4+8].