Indexing with Extended Registers
From the 80386 on, indexing and based indexing of great power and
flexibility was allowed using the extended registers eax, ebx, ecx,
edx, esi, edi, esp, and ebp.
The addressing combinations avaiable are:
  address_expression + base_register + scale * index_register
The base_register and index_register can be any of the eight registers.
The scale will match what you are trying to get, byte, 
word, double word, or quad word.  Obviously,
some of this will not work when in the 16-bit mode.
Example
Let W be an array of words and N a subscript ina 
word variable.  The assembly code to do the following C code 
  
W[N + 3] = 27;
  
would be:
	sub	edx, edx	; zero upper half of edx
	mov	dx, N
	mov	[W + 6 + 2 * edx], 27
  
lea Instruction
There is an instruction to load the effective address of a memory
location such that the code:
  
	mov	ax, OFFSET msg
  
could be replaced with:
  
	lea	ax, msg
  
By using fancier forms for memory addressing, we can get:
  
  	lea	eax, [eax + 4       ]	;add 4 to eax(!)
	lea	eax, [eax + 2 * eax ]	; eax = eax * 3
	lea 	eax, [      4 * eax ]	; eax = eax * 4
	lea	eax, [eax + 4 * eax ]  	; eax = eax * 5
  
Notice that this works as a fast multiplication of
small numbers and does not change the flags!
 UMBC  |
 CSEE