Using+the+lea+instruction

//by Richard Russell, July 2007//

Beginners in x86 (or IA-32) assembly language programming often fail to appreciate the value of the **lea** (Load Effective Address) instruction and use it rarely, if at all. **lea** takes advantage of the CPU's address generator(s) in being able to perform some simple calculations on 32-bit values which do not tie-up the resources of the CPU's Arithmetic Logic Unit(s). In so doing the resulting code can be shorter and faster.

This is particularly so on modern processors, because the address generators are likely to be relatively underused and may be available to perform a calculation //in parallel with// other operations taking place on the ALUs. Also, because the **lea** instruction doesn't affect the condition flags it doesn't //stall// other instructions which may be dependent on the state of those flags, hence they can be executed simultaneously rather than sequentially.

To take an extreme example, suppose you want to perform the following register arithmetic:

code format="bb4w" eax = ebx*4 + ecx + constant code That is, add four-times **ebx** to **ecx**, add a constant, then put the result into **eax**.

A simplistic approach, using the ALU, would require code like the following:

code 00100000 8B C3                 mov eax,ebx 00100002 C1 E0 02              shl eax,2 00100005 03 C1                 add eax,ecx 00100007 05 40 E2 01 00        add eax,constant code However using **lea** we can do it in just one instruction:

code 00100000 8D 84 99 40 E2 01 00  lea eax,[ecx+ebx*4+constant] code Not only is this five bytes shorter, it is likely to execute considerably more quickly.

Of course the limitation of **lea** is that only certain arithmetic operations - those required for address generation - are available. Basically it can add any 32-bit register (or none) to 1, 2, 4 or 8 times any other 32-bit register, and optionally add a constant to the result. Since it can add a register to 2, 4, or 8 times the //same// register, it can also multiply a register by 3, 5 or 9:

code 00100000 8D 04 5B              lea eax,[ebx*3] 00100003 8D 04 9B              lea eax,[ebx*5] 00100006 8D 04 DB              lea eax,[ebx*9] code