查看汇编代码片段,我看到:

lea rax, [rbp-0x50]


告诉我,rax寄存器现在指向rbp-hex(50)中的任何值。

问题。我这样做会达到相同的结果吗? :

mov rax, dword ptr [rbp-0x50]


如果是这样,那么lea指令又有什么需要?

感谢您在我进入64b汇编程序时的耐心配合。

#1 楼

lea =地址
mov =内容

如果地址0x401000包含0xDeadBeef,如ef be ad de

lea MySecretPlace,[401000] MySecretPlace将为0x401000
Mov MySecretPlace,[401000] MySecretPlace将为DeadBeef

mov MySecretPlace,字节ptr [401000] MySecretPlace将为0xef 0r 0xef,具体取决于EndianNess




在一个小演示下找到


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


编译并与

:\>bld.bat lea

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

链接

执行

:\>lea.exe
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'
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:


#2 楼

这是基本的。假设rpb的值为55h(汇编程序语法)。然后
lea rax, [rbp-50h]
会导致5。

,因此,区别在于第一个是直接的,第二个是间接的。
顺便说一句,您可以轻松尝试一下!

评论


谢谢,但是“ dword ptr”会做什么?我们可以忽略它吗?我的印象是,双字ptr [rbp-0x50]只会将地址作为值返回,而不是返回实际数据

–user3732445
2月18日下午22:35

前缀dword ptr通常意味着括号中的源操作数是指向双字(即32位)的指针。您建议的代码似乎无效,因为在左侧有一个64位寄存器,在右侧有32位值。汇编程序(VS2019)抱怨“指令操作数必须大小相同”。因此,您可以编写mov rax [rbp-50h]来传送64位值,或者编写mov eax dword ptr [rbp-50h]。进行32位传送。 eax是rax的低32位。

–乔什
2月18日23:57



#3 楼

区别在于,lea仅计算地址,而mov实际移动数据。如果您了解C或C ++,则有点类似于:


Lea:rax = rbp + 0x50;

Mov:rax = rbp[0x50];


(由于计数方式不同,因此不等同于组装)