1

When you are using both the MOV and LEA instructions in assembly, what does it really mean when someone writes:

   mov DWORD PTR [esp+4], 0x80484c 
   lea eax,[ebp-40]

Specifically, when they write the information in the brackets []. I know that lea moves addresses and mov moves content, but when they are computing the addresses in lea or mov, how does that actually work? Is it the same as pointer arithmetic in C?

  • 3
    `Is it the same as pointer arithmetic in C?` - No, it isn't. A comprehensive answer can be found in any decent x86 assembly documentation/book, and freely available around. – Eugene Sh. Jul 31 '16 at 14:40
  • Keep in mind that there is no real memory access in `lea` : it merely calculates the address of the operand, and stores it. Compilers sometimes use it to perform unsigned arithmetic - though not in this particular case, it seems. – Daniel Kamil Kozar Jul 31 '16 at 14:44
  • Not only can comprehensive answers be found in assembly documentation, you can find lots of very comprehensive and clear answers here with a quick search. – David Hoelzer Aug 01 '16 at 00:14

2 Answers2

4

lea does not move addresses, it computes the effective address and stores the resulting address into the destination register. Address computations are performed in machine language with regular arithmetic, not C pointer arithmetic.

lea eax,[ebp-40]

subtracts 40 from the value in register ebp and stores the result in register eax.

mov DWORD PTR [esp+4], 0x80484c

Computes the destination address by adding 4 to the value contained in register esp and stores the value 0x80484c, the integer 8407116, as a 32 bit integer occupying 4 bytes at that address, least significant byte first.

chqrlie
  • 131,814
  • 10
  • 121
  • 189
3

lea just calculates an expression and saves it to variable. It doesn't actually do anything with memory or memory addresses even through it is named 'load effective address'.

For example lea eax,[ebp-40] means eax = ebp - 40.

It can be used to calculate expressions which would otherwise take several instructions, for example:

lea eax, [8 * eax + ebx + 10]

calculates eax = 8 * eax + ebx + 10 with one instruction.

On the other hand mov, when used with [...], read/writes something from/to memory, so it's a bit like using C pointers.

mov DWORD PTR [esp+4], 0x80484c

This saves 32-bit unsigned integer (DWORD) value 0x80484c to memory location esp + 4, i.e. same as following pseudo-C:

*((uint32_t*)(esp + 4)) = 0x80484c;
Markus Laire
  • 2,837
  • 2
  • 17
  • 23
  • So could you say that every register starts out without any bits/bytes in it, and in order to move values into those registers, you have to add bytes to those registers? So if I wanted to move a 32 bit int into register EAX, I would have to say: mov DWORD PTR [EAX+4], (32 bit int)? – John Conrad Geenty Jul 31 '16 at 16:40
  • @JohnConradGeenty No. CPU registers are just internal variables of the CPU. For example `eax` is 32-bit register and will always contain some 32-bit value exactly a 32-bit variable would. (Google about X86 assembly registers to learn more.) – Markus Laire Jul 31 '16 at 16:49
  • @JohnConradGeenty To move value into register, you use `mov eax, (32 bit value)`. I edited my answer to mention that only with `[...]` will `mov` access memory. – Markus Laire Jul 31 '16 at 17:04