9

Looking at an assembly code snippet I see:

lea rax, [rbp-0x50]

Which tells me that the rax register now points to whatever value is in rbp-hex(50).

Question. Would I achieve the same result doing this? :

mov rax, dword ptr [rbp-0x50]

If so, what is the need for the lea instruction anyways?

Thank you for your patience as I am diving into 64b assembler.

user3732445
  • 321
  • 1
  • 3
  • 6

4 Answers4

8

lea = address
mov = contents

if address 0x401000 contains 0xDeadBeef like ef be ad de

lea MySecretPlace, [401000] MySecretPlace will be 0x401000
Mov MySecretPlace, [401000] MySecretPlace will be DeadBeef

mov MySecretPlace, byte ptr [401000] MySecretPlace will be 0xef 0r 0xef depending on EndianNess

mov MySecretPlace, word ptr [401000] MySecretPlace will be 0xdead 0r 0xadde depending on EndianNess

enter image description here

find below a small demo
source

:\>cat lea.cpp
#include <stdio.h>
int main (void) {
    unsigned int secret = 0xdeadbeef;
    printf("DWORD PTR ds:[%p] == %x\n" , &secret,*(unsigned int   *)&secret);
    printf("WORD  PTR ds:[%p] == %x\n" , &secret,*(unsigned short *)&secret);
    printf("BYTE  PTR ds:[%p] == %x\n" , &secret,*(unsigned char  *)&secret);
        return 0;
}

compiled and linked with

:\>bld.bat lea

:\>cl /Zi /W4 /O1 /analyze /EHsc /nologo  lea.cpp /link /release
lea.cpp

executed

:\>lea.exe
DWORD PTR ds:[0030F7DC] == deadbeef
WORD  PTR ds:[0030F7DC] == beef
BYTE  PTR ds:[0030F7DC] == ef

disassembled

:\>cdb -c "uf lea!main;q" lea.exe 
0:000> cdb: Reading initial command 'uf lea!main;q'
lea!main:
00fe1029 55              push    ebp
00fe102a 8bec            mov     ebp,esp
00fe102c 51              push    ecx
00fe102d b8efbeadde      mov     eax,0DEADBEEFh
00fe1032 50              push    eax
00fe1033 8945fc          mov     dword ptr [ebp-4],eax
00fe1036 8d45fc          lea     eax,[ebp-4]
00fe1039 50              push    eax
00fe103a 6890010201      push    offset lea!`string' (01020190)
00fe103f e82d000000      call    lea!printf (00fe1071)
00fe1044 0fb745fc        movzx   eax,word ptr [ebp-4]
00fe1048 50              push    eax
00fe1049 8d45fc          lea     eax,[ebp-4]
00fe104c 50              push    eax
00fe104d 68ac010201      push    offset lea!`string' (010201ac)
00fe1052 e81a000000      call    lea!printf (00fe1071)
00fe1057 0fb645fc        movzx   eax,byte ptr [ebp-4]
00fe105b 50              push    eax
00fe105c 8d45fc          lea     eax,[ebp-4]
00fe105f 50              push    eax
00fe1060 68c8010201      push    offset lea!`string' (010201c8)
00fe1065 e807000000      call    lea!printf (00fe1071)
00fe106a 83c424          add     esp,24h
00fe106d 33c0            xor     eax,eax
00fe106f c9              leave
00fe1070 c3              ret
quit:
blabb
  • 16,376
  • 1
  • 15
  • 30
3

This is basic. Assume that rpb has a value of 55h (Assembler syntax). then lea rax, [rbp-50h] would result in 5.

On the other hand, mov rax, [rbp-50h] would most probable crash your application, as it would try to read the content of the address 5 and put it into rax.

Thus, the difference is that the first is direct, the second indirect. BTW, you can easily try it out yourself!

josh
  • 1,974
  • 12
  • 9
  • thanks, but what would "dword ptr" do? Can we just ignore it? I was under the impression that the dword ptr [rbp-0x50] would only return the address as a value, not the actual data on it – user3732445 Feb 18 '20 at 22:35
  • The prefix dword ptr usually means that your source operand in the brackets is a pointer to a doubleword, i.e. 32 bits. Your suggested code seems to be invalid, as on the left side you have a 64-Bit register, and on the right side a 32-bit value. The assembler (VS2019) complains "Instructions operands must be the same size". Thus, either you write mov rax, [rbp-50h] to transfer 64-Bit values, or mov eax, dword ptr [rbp-50h].for 32-bit transfer. eax is the low 32 bit of rax. – josh Feb 18 '20 at 23:57
3

Warning: Illegal instruction used for explanation.
If you are wondering if mov can do the work of lea,
mov eax, esp+4 and lea eax, [esp+4] copies the same value to eax.
However, mov eax, esp+4 is not a legal instruction! (esp+4 is not a legal addressing mode.)
But then, can you replace lea eax, [esp+4] with the following?

mov eax, esp
add eax, 4

Not really! The value of eax after executing the above instructions will match lea eax, [esp+4]. But they are still not the same! this is because add instruction may modify flags while lea does not.

2

The difference is that lea only calculates the address while mov actually moves the data. If you know C or C++, it’s somewhat similar to:

  1. Lea:rax = rbp + 0x50;
  2. Mov: rax = rbp[0x50];

(Not equivalent to assembly because of different way of counting)

Igor Skochinsky
  • 36,553
  • 7
  • 65
  • 115