0

lea is used in to assign pointers to variables.

    int x = 44;
    int p = &x;

becomes the following:

    mov     DWORD PTR [rbp-8], 44  ; We move 44 into a local variable
    lea     rax, [rbp-8]           ; We take the address of the local variable and assign it to RAX
                                   ; There is no memory to memory addressing form, hence why our
                                   ; destination is a register and not a local variable on the stack
    mov     DWORD PTR [rbp-4], eax ; We do a mov because mov supports register to memory

In the above lea actually dereferences rbp-8. In other words, it takes what is located at the address stored in rbp minus 8.

In this example, lea does not dereference the register. It instead performs arithmetic on the value stored in the register.

int add_three(int value) {
    return value + 3; 
}

becomes the following:

add_three:
     lea     eax, [rdi+3]
     ret

In the above. lea does not derference rdi plus 3 as it did with rbp minus 4. Instead, it takes the value stored in rdi and adds 3.

My question is, are there other instances where lea actaully derferences a register in the same with it will registers referring to local variables (e.g., rbp -4 or rsp + 8)?

Peter Cordes
  • 286,368
  • 41
  • 520
  • 731
Happy Jerry
  • 124
  • 1
  • 8
  • "In the above `lea` actually dereferences `rbp-8`. In other words, it takes what is located at the address stored in `rbp` minus 8." No it doesn't. – Joseph Sible-Reinstate Monica Jun 05 '22 at 05:43
  • https://stackoverflow.com/questions/1658294/whats-the-purpose-of-the-lea-instruction – Support Ukraine Jun 05 '22 at 05:51
  • You mean used for address math, with an addressing mode that GCC could or does use to actually access a variable? Like the opposite of [Using LEA on values that aren't addresses / pointers?](https://stackoverflow.com/q/46597055) LEA *never* accesses memory, so it never *actually* dereferences anything. Or in terms of syntax, it always requires a memory addressing mode. `scanf("%d", some_global)` would be a simple case where GCC `-fPIE` would use a RIP-relative LEA. Like [How to load address of function or label into register](https://stackoverflow.com/q/57212012) – Peter Cordes Jun 05 '22 at 06:18
  • Or for looping over an array, `int *endp = p + size;` often compiles to an LEA. Basically, think of any case where an LEA on actual addresses would be an most efficient way to do something (or the *most* efficient), and then check on https://godbolt.org/ to see if clang or gcc `-O3` do that. – Peter Cordes Jun 05 '22 at 06:21
  • It's a pity that `lea` exists as a mnemonic in assembly language - it would've been better (to avoid confusion, etc) if assemblers and disassemblers just used `mov` (e.g. like `mov rax, rbx*8 + rdx + 123`) for the corresponding opcode/machine code. – Brendan Jun 05 '22 at 09:00

0 Answers0