LEA or ADD instruction?

Viewed 24127

When I'm handwriting assembly, I generally choose the form

lea eax, [eax+4]

Over the form..

add eax, 4

I have heard that lea is a "0-clock" instruction (like NOP), while 'add' isn't. However, when I look at compiler produced Assembly I often see the latter form used instead of the first. I'm smart enough to trust the compiler, so can anyone shed some light on which one is better? Which one is faster? Why is the compiler choosing the latter form over the former?

5 Answers

The main reason is next. As you can note if you look carefully at the x86, this ISA is two-address. Every instruction accepts at most two arguments. Thus, the semantic of operations is next:

DST = DST <operation> SRC

The LEA is a kind of hack instruction, because it is the SINGLE instruction in the x86 ISA which is actually three-address:

DST = SRC1 <operation> SRC2

It is a kind of hack instruction, because it reuses the arguments dispatcher circuit of x86 CPU for performing addition and shift.

Compilers use LEA because this intruction allows them to replace few intructions by single instruction in the cases when the content of summand registers is beneficial to preserve unchanged. Take a note, that in all cases when compiler uses LEA DST register differs from the SRC register or SRC argument exploits complex address calculation logic.

For example, it is almost impossible to find in the generated code such use case:

LEA EAX, [EAX   ] // equivalent of NOP
LEA EAX, [ECX   ] // equivalent of MOV EAX, ECX
LEA EAX, [EAX+12] // equivalent of ADD EAX, 12

but the next use cases are common:

LEA EAX, [ECX      +12] // there is no single-instruction equivalent
LEA EAX, [ECX+EDX*4+12] // there is no single-instruction equivalent
LEA EDX, [ECX+EDX*4+12] // there is no single-instruction equivalent

Indeed, imagine the next scenario with assumption that value of EBP should be preserved for future use:

LEA EAX, [EBP+12]
LEA EDX, [EBP+48]

Just two instructions! But in the case of absence of LEA the code will be next

MOV EAX, EBP
MOV EDX, EBP
ADD EAX, 12
ADD EDX, 48

I believe that the benefit of LEA use should be evident now. You can try to replace this instruction

LEA EDX, [ECX+EDX*4+12] // there is no single-instruction equivalent

by ADD-based code.

Related