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.


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

:\>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


DWORD PTR ds:[0030F7DC] == deadbeef
WORD  PTR ds:[0030F7DC] == beef
BYTE  PTR ds:[0030F7DC] == ef


:\>cdb -c "uf lea!main;q" lea.exe 
0:000> cdb: Reading initial command 'uf lea!main;q'
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

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!

  • 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

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.


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)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.