3

In assembly, the square brackets [] seem to have the same meaning as * in C programming language. They are used to dereference a pointer. Dereferencing a pointer means going to refer to a specific memory location to read or write it.

So, it is quite logical to use square brackets in the case of a MOV. But what is the logical reason why they also use it for LEA?

LEA EAX, [EBP -4], looks like dereferencing a pointer, EBP - 4, to refer to the pointed memory location but it will not read the value contained in the location but rather the address.

I'm a little confused about this. Could you give me the right way to think about this?
Does LEA have any connection with the concept of dereferencing? Clearly not intended as a memory reading, but mostly as referring to a location of memory not for its value, but for its address. I wouldn't want this to become a philosophical question.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Tony92
  • 95
  • 1
  • 6

1 Answers1

5

The LEA instruction is designed to look like a memory access instruction — so can perform all the addressing modes.  The difference, of course, as you're noting is that LEA loads the "effective address" rather than a memory value from that location.

Thus, LEA is similar to memory access operations, but specifically, in C terms, is taking the address — so like &a[i] in C.  Like in C with &, the result of LEA is always a pointer sized value rather than with real accesses where we can fetch/store a byte, word, etc..

Erik Eidt
  • 23,049
  • 2
  • 29
  • 53
  • I make an example in C ++. int i = 10; int ptr_i = &i; int* ptr2_i = &*ptr_i in this case ptr2_i will contain the address of i. &*ptr_i is as if I were saying *ptr_i goes to dereference this pointer to refer to the memory location of i, but then due to & does not read the value of the location but the address. Is this correct ? – Tony92 Nov 20 '19 at 17:48
  • 2
    Yes, the & and * cancel out generally speaking (so do * and & cancel out, generally speaking), so the latter (`ptr2_i =`) is simply a direct assignment of (pointer) values with no memory dereferencing. The former (`int ptr_i = &i`) could use the `lea` with `[rbp-n]` addressing mode to compute the address of `i`, with `i` as a local variable (it is on the stack, instead of in a register, since only memory variables have addresses whereas register variables don't.. taking `&i` basically forces `i` to be located in a memory location so that it has an obtainable address). – Erik Eidt Nov 20 '19 at 21:53