0

I am not sure if this is an duplicate, but I couldn’t find any answer I want in the similar posts, so feel free to write the link down and close this question if there is an answer.

I am currently studying x86-64 assembly language. From my knowledge, LEA is intended to be used to compute the some arithmetic of the address, and then copy the address into the destination. There is also a lot of case where LEA is just used to compute some arithmetic of some values. Assume x is stored in register %rdi:

long m12(long x){ return x*12; }

Assembly code:

leaq (%rdi,%rdi,2), %rax

salq $2, %rax

Here the return value from the leaqwould be 3*x. However I have also seen something similar using mov:

movl (%rdx,%rcx,4), %eax

What is the difference between these two?

JAKB824
  • 81
  • 7
  • I'm quite sure this is a duplicate. Lea only calculates the address of `5*rdi` storing the 64-bit address to `rax`, while `movl` accesses the 64-bit memory address and reads the 4-byte content to `eax`. – Aki Suihkonen Dec 05 '20 at 13:27
  • @AkiSuihkonen The ```leaq```operation is generated by the compiler from a function that simply returns x*12. The compiler first uses leaq to get 3*%rdi, computes the result into %rax, and then shift %rax left by 2. This example is from textbook – JAKB824 Dec 05 '20 at 13:46
  • 1
    Whether you're going to use the value computed by `lea` as an address isn't really relevant. https://stackoverflow.com/questions/1699748/what-is-the-difference-between-mov-and-lea seems like a suitable duplicate. – Michael Dec 05 '20 at 13:49
  • @Michael Please see the edited question. I found a question with the exact same example, https://stackoverflow.com/questions/46597055/using-lea-on-values-that-arent-addresses-pointers/46597375#46597375, but I still can’t seem to find the answer. – JAKB824 Dec 05 '20 at 13:58
  • The answer to what? The `lea` calculates `rax = rdi*3`, while the `mov` loads a dword from memory at the address `rdx + rcx*4`. They are two completely different operations. – Michael Dec 05 '20 at 14:07
  • My answer on [Using LEA on values that aren't addresses / pointers?](https://stackoverflow.com/q/46597055) assumes you already know that MOV with a memory source operand is a load from memory, unlike LEA. It's not a duplicate of that because you have a different misunderstanding. I think it *is* a duplicate of the question Michael linked, though, or at least of both together. You do need to understand what `mov` does, and that it can't do math except for actual address-generation. – Peter Cordes Dec 05 '20 at 14:07
  • @Michael, sorry, what I meant was the if we have the same thing but replacing lea with mov: ```movq (%rdi,%rdi,2), %rax```, does that make any difference, or is this even legal? The example i wrote for the mov in the question is trying to say that both lea and mov are computing values. – JAKB824 Dec 05 '20 at 14:14
  • @PeterCordes My understanding on mov is that it does the math, and pass the value in the computed address to the destination. – JAKB824 Dec 05 '20 at 14:27
  • 2
    No, that's what LEA does. MOV uses the computed address to access memory, as explained in the linked duplicate. Especially [one of the later answers](https://stackoverflow.com/a/60272214/224132), – Peter Cordes Dec 05 '20 at 14:30
  • @PeterCordes So I guess in my example I can’t simply replace the LEA to MOV to compute the 3*x, as that is not an address that can be dereferenced, am I right? MOV will dereference the computed result. – JAKB824 Dec 05 '20 at 14:48
  • 2
    Yes, of course, that's why there are 2 different instructions. It would obviously be pointless to have 2 instructions that did exactly the same thing in all cases. – Peter Cordes Dec 05 '20 at 14:52

0 Answers0