3

The following C code:

int sum(int x, int y) {
    return x + y;
}

Compiles to:

add:
        leal    (%rdi,%rsi), %eax
        ret

I've only seen lea used to move a memory address from one place to another, but here is seems to be moving a value-sum into eax. How does that work?

carl.hiass
  • 1,526
  • 1
  • 6
  • 26

1 Answers1

7

Indeed, lea is an abbreviation for "load effective address" and therefore it was originally intended to perform address calculations.

However: Does it make any difference if the result of the calculation rsi+rdi is an address or some integer number?

For the CPU it does not make any difference!

For this reason you can use this instruction instead of add if you do not require flags to be set.

The operation rax=rsi+rdi can be done using one lea instruction or using a combination of two instructions: mov and add.

Using only one instruction is typically faster and shorter than using two instructions.

And you can even use the instruction (leal (%rsi,%rdi),%rax) to perform an 8-, 16- or 32-bit addition because by performing the operation rax=rsi+rdi you implicitly perform the operations eax=esi+edi, ax=si+di and al=sil+dil.

If I understand your code correctly, a 32-bit addition (eax=esi+edi) is done by the C code.

Martin Rosenau
  • 17,897
  • 3
  • 19
  • 38
  • +1 for pointing (aha ha) out that `lea` does not affect the flags register. The ability to interleave simple arithmetic performed by `lea` without affecting things like carry flags, or flags used for flow control, is critical to performance in many cases. – Brett Hale Aug 30 '20 at 07:42