IA32 Addressing Modes and leal

Complete Memory Addressing and leal

IA32 General Memory Addressing

The complete memory addressing form is:
  D(Rb,Ri,S)   # Mem[Reg[Rb]+S*Reg[Ri]+ D]
 D,Rb,Ri,S are used together to compute a memory address
      Rb:     Base register             
      Ri:     Index register
      S:      Scale: often 1, 2, 4, or 8     Q: why 1, 2, 4 or 8?
      D:      Constant "displacement" 
     D(Rb,Ri,S)  # Mem[Reg[Rb]+S*Reg[Ri]+ D]   
For example, an instruction could specify a memory operand as:
addl 8(%ecx, %eax, 4), %edx  # R[%edx] <-- M[R[%ecx] + 4*R[%eax] + 8]
There are a lot of Special Cases of this general form (not all 4 values need to be present):
 D(Rb,Ri,S)  # Mem[Reg[Rb]+S*Reg[Ri]+ D]   The General Form
  (Rb,Ri,S)  # Mem[Reg[Rb]+S*Reg[Ri]]
   (Rb,Ri)   # Mem[Reg[Rb]+Reg[Ri]]
  D(Rb,Ri)   # Mem[Reg[Rb]+Reg[Ri]+D]
   (,Ri,S)   # Mem[S*Reg[Ri]]
  D(,Ri,S)   # Mem[S*Reg[Ri] + D]
  (Rb)       # Mem[Reg[Rb]]        we have already seen this form: (%eax)
  D(Rb)      # Mem[Reg[Rb]+D]      we have already seen this form: -8(%ebp)
  D          # Mem[D]              we have already seen this form: $10
Let's try out some examples of computing address (fill in the table):
Assume:
  %edx stores 0xf000
  %ecx stores 0x0100

Address Expression        Address Computation          Address
--------------------------------------------------------------
   0x8(%edx)
   (%edx, %ecx)
   (%edx, %ecx, 4)
   0x80(, %ecx, 2)
(answers)

Introduction to the leal instruction

Load effective address: leal S,D # D<--&S, where D must be a register, and S is a Memory operand.

leal looks like a mov instr, but does not access Memory. Instead, it takes advantage of the addressing circuitry and uses it to do arithmetic (as opposed to generating multiple arithmetic instructions to do arithmetic).

(ex) if edx holds the value of x:
 leal (%eax),%ecx  # R[%ecx]<--&(M[R[%eax]])       
 # this moves the value stored in %eax to %ecx
The key is that the address of (M[ at address x ]) is x, so this is moving the value stored in %eax to %ecx; there is no memory access in this instruction's execution.

Examples:

Assume:   %eax: x    %edx: y

leal (%eax), %ecx               # R[%ecx] <-- x
leal 6(%eax), %ecx              # R[%ecx] <-- x+6
leal 7(%edx, %edx, 4), %ecx     # R[%ecx] <-- 5y + 7 (y + 4y+ 7)
leal 10(%eax, %edx, 5), %ecx    # R[%ecx] <-- x + 5y + 10: 
leal appears often in compiler generated code. You can think of leal as nice shorthand for computing expressions that follow the address computation pattern.

One thing to keep in mind is that leal is not a regular arithmetic instruction. This means that unlike the regular arithmetic instructions leal does NOT set condition codes. If a computation part of a condional expression whose result a conditional jump instruction will use, leal cannot be used (add or mult instructions need to be used in this case).