0

From this answer:

lea eax, [eax*4] == shl eax, 2 ; but without setting flags

So, I think lea loads the value(not address) of eax here and lea does the following things:

  1. access the value stored in eax
  2. <<2
  3. load the calculated value into eax

But this answer says:

LEA loads a pointer to the item you're addressing

Does the two conflict? If lea can only Load Effective Address, how does it shl the value? Where do I understand wrong?

Chen Li
  • 4,824
  • 3
  • 28
  • 55
  • See [What's the purpose of the LEA instruction?](https://stackoverflow.com/a/1658310/16673): LEA, the only instruction that performs memory addressing calculations but doesn't actually address memory. – Suma Jun 13 '18 at 11:42
  • @Suma I have read this QA before asking the question. But I am not sure can I say "`lea` in my question load the value(not address)" – Chen Li Jun 13 '18 at 11:48
  • 1
    the "effective address" of `[eax*4]` is eax*4, if you load eax with eax*4 this is pretty much "multiplying by 4", which is exact the same like `shr eax,2` does. (without setting the flags, but that's already said in the comment) – Tommylee2k Jun 13 '18 at 11:49
  • @Tommylee2k Thanks. But IIUC, `[eax*4]` still needs the value stored in `eax` to complete the multiplying, right? Or what you mean is, what [eax*4] does is not belong to `lea`, `lea` only needs the final effective address of `[eax*4]`? – Chen Li Jun 13 '18 at 12:00
  • 1
    You could have just tried this with a value that wasn't a legal pointer and see if it faulted, or with a location that didn't point to itself and look at the resulting value in a register. **`lea` is a shift-and-add ALU instruction; it doesn't touch memory. [Using LEA on values that aren't addresses / pointers?](https://stackoverflow.com/a/46597375)**. It uses memory-operand syntax and machine-encoding because the CPU can already decode addressing modes. – Peter Cordes Jun 13 '18 at 15:01

1 Answers1

1

Does lea in “lea eax, [eax*4]” load the value?

no it doesn't:

I think what confuses you are the brackets '[ ]'

[1234] is the "value at address 1234", the "effective address" of it is 1234 (brackets removed)

so LEA EAX, [4*EAX] loads the effective address of [4*EAX] which is 4*EAX

The content of EAX is (of course read), the value in memory at [4xEAX] isn't

in fact LEA <reg>, [something] is pretty much the same like MOV <reg>, something, while LEA can do some basic arithmetics (x2, x4, x8, adding offset), and MOV can't

Tommylee2k
  • 2,683
  • 1
  • 9
  • 22
  • But how can `[eax*4]` be done without loading/accessing the value of `eax`? I think `eax` in `[eax*4]` is its value, rather than its address. – Chen Li Jun 13 '18 at 12:16
  • `eax` **is** accessed. Memory at address `eax*4` is not (which is what `mov` would do). – Jester Jun 13 '18 at 12:16
  • 1
    @陳 力 don't mix "the value of eax" (which is eax, and has no address :) ) and "the value of [eax]" – Tommylee2k Jun 13 '18 at 12:21
  • @Tommylee2k Ok, let me re-organize the question: But how can `[eax*4]` be done without loading/accessing the value of *eax* (AKA, `[eax]`)? I think *eax* in `[eax*4]` is its value(`[eax]`), rather than its address(`eax`). – Chen Li Jun 13 '18 at 12:25
  • 2
    `[eax]` with the brackets means content of **memory** at address `eax`. The difference between the `mov` and the `lea` is that the **memory** is not accessed, not the register's value which of course is. You can think of the `[]` as the `*` operator in C, and the `lea` as the `&` operator. – Jester Jun 13 '18 at 12:27
  • `"eax"` is a register, to access it's value no memory has to be read. `"[eax]"` is the content of the memory eax is pointing to (NOT "the value of eax" !! ) – Tommylee2k Jun 13 '18 at 12:45
  • Thanks, @Jester . I think I didn't misunderstand [eax] and eax. "The difference between the `mov` and the lea is that the memory is not accessed, not the register's value which of course is" may be the key to solve my confusion, but I used to think `access the memory == achieve value`, just as what you said in the front "[eax] with the brackets means **content of memory** at address eax". Can you explain more about the difference between "access it's value" and "read memory"? Thanks! – Chen Li Jun 13 '18 at 12:52
  • `eax` is always accessed. If you do `mov eax, [eax*4]` that's roughly `eax = *(eax*4)` hence memory access. If you do `lea eax, [eax*4]` that is `eax = &*(eax*4)` where the `&` and the `*` cancel so you get `eax=eax*4` – Jester Jun 13 '18 at 12:55
  • @Tommylee2k Ok, so I mis-use the terms...(I read some articles say "register have two property: value and address" in the past). Can you give me some cases which memory is accessed?(Like what I said above, I always thought achieve value == access memory, because in c, `*p` just achieve the value stored in address) – Chen Li Jun 13 '18 at 12:56
  • @Jester Thanks, nice example! – Chen Li Jun 13 '18 at 13:08
  • @陳力: registers don't *have* addresses. They can *hold* pointer values, which *are* addresses. But pointers are just a special kind of integer in assembly language. – Peter Cordes Jun 13 '18 at 15:07
  • @PeterCordes Thanks. Now I know the pointer value is also the content of register. But whose address? As you have said, *registers don't have addresses*. In other words, now that register have no address, how can the assembler find the content from the pointer value(AKA addresses) – Chen Li Jun 15 '18 at 07:20
  • @陳力: Go read [Using LEA on values that aren't addresses / pointers?](https://stackoverflow.com/a/46597375) again. LEA is a shift-and-add instruction with register sources. It doesn't matter whether the values are valid pointers or not; LEA doesn't care about anything pointing to anything. – Peter Cordes Jun 15 '18 at 07:42