Assembly 为什么有多个移动而不是一个移动?

Assembly 为什么有多个移动而不是一个移动?,assembly,x86,Assembly,X86,我正在检查gdb中的反汇编程序,我发现了这些行,不明白为什么它会这样做 0x00000000004005ef <+50>: mov rax,QWORD PTR [rbp-0x10] 0x00000000004005f3 <+54>: add rax,0x8 0x00000000004005f7 <+58>: mov rax,QWORD PTR [rax] 0x00000000004005ef:mov-rax,QWORD-PTR[

我正在检查gdb中的反汇编程序,我发现了这些行,不明白为什么它会这样做

0x00000000004005ef <+50>:   mov    rax,QWORD PTR [rbp-0x10]
0x00000000004005f3 <+54>:   add    rax,0x8
0x00000000004005f7 <+58>:   mov    rax,QWORD PTR [rax]
0x00000000004005ef:mov-rax,QWORD-PTR[rbp-0x10]
0x00000000004005f3:添加rax,0x8
0x00000000004005f7:mov-rax,QWORD-PTR[rax]
为什么它没有这样做呢

0x00000000004005ef <+50>:   mov    rax,QWORD PTR [rbp-0x8]
0x00000000004005ef:mov-rax,QWORD-PTR[rbp-0x8]
我不这么认为:

(a)

0x00000000004005ef:mov-rax,QWORD-PTR[rbp-0x10];从地址开始移动8字节
; [rbp-0x10]至rax
0x00000000004005f3:添加rax,0x8;rax=rax+0x08
0x00000000004005f7:mov-rax,QWORD-PTR[rax];从地址开始移动8字节
; [rax]到rax
(b)

0x00000000004005ef:mov-rax,QWORD-PTR[rbp-0x8];从地址开始移动8字节
; [rbp-0x8]至rax
“a”看起来像是加载地址、应用(整数)偏移量和取消引用地址的代码的一部分。但是,“b”的起始地址是不同的(并且没有读取来自不同地址的值)。

我不这么认为:

(a)

0x00000000004005ef:mov-rax,QWORD-PTR[rbp-0x10];从地址开始移动8字节
; [rbp-0x10]至rax
0x00000000004005f3:添加rax,0x8;rax=rax+0x08
0x00000000004005f7:mov-rax,QWORD-PTR[rax];从地址开始移动8字节
; [rax]到rax
(b)

0x00000000004005ef:mov-rax,QWORD-PTR[rbp-0x8];从地址开始移动8字节
; [rbp-0x8]至rax

“a”看起来像是加载地址、应用(整数)偏移量和取消引用地址的代码的一部分。但是,“b”是不同的起始地址(并且没有读取来自不同地址的值)。

[rbp-0x8]
[rbp-0x10]
是两个不同的局部变量。您的代码与反汇编代码完全不同

使用下面的c代码

{
  int64_t a;    // [rbp-0x8] is a
  int64_t *p;   // [rbp-0x10] is p; not *p
  ...
}
该程序将把
*(p+1)
(1 int64的大小为8字节)输入到
RAX

MOV  RAX, [rbp-0x10]  ; RAX <-- p
ADD  RAX, 8           ; RAX <-- p + 1
MOV  RAX, [RAX]       ; RAX <-- *(p + 1) 

[rbp-0x8]
[rbp-0x10]
是两个不同的局部变量。您的代码与反汇编代码完全不同

使用下面的c代码

{
  int64_t a;    // [rbp-0x8] is a
  int64_t *p;   // [rbp-0x10] is p; not *p
  ...
}
该程序将把
*(p+1)
(1 int64的大小为8字节)输入到
RAX

MOV  RAX, [rbp-0x10]  ; RAX <-- p
ADD  RAX, 8           ; RAX <-- p + 1
MOV  RAX, [RAX]       ; RAX <-- *(p + 1) 

ITYM
mov rax,QWORD PTR[rbp-0x8]
?是的,很抱歉,如果您希望asm不可怕,请键入编译并启用优化。但是,我们没有足够的上下文来更有效地实现第一个序列,除非在这种情况下我们可以优化掉局部序列。但无论如何,寻址模式中的偏移量与加载/存储的值的变化是分开的。第二个版本与第一个版本没有任何相似之处。我们需要查看编译的原始代码,这可能很有意义,可能是高级代码规定了类似的功能。也没有理由假设优化器是完美的,在任何像样的/实际规模的项目中,至少有一个地方(如果不是很多的话)有很多机会改进编译器的输出。ITYM
mov rax,QWORD PTR[rbp-0x8]
?是的,很抱歉,如果您想要不可怕的asm,请键入启用优化的编译。但是,我们没有足够的上下文来更有效地实现第一个序列,除非在这种情况下我们可以优化掉局部序列。但无论如何,寻址模式中的偏移量与加载/存储的值的变化是分开的。第二个版本与第一个版本没有任何相似之处。我们需要查看编译的原始代码,这可能很有意义,可能是高级代码规定了类似的功能。也没有理由假设优化器是完美的,在任何像样的/实际规模的项目中,至少有一个地方(如果不是很多地方的话)有很多机会改进编译器的输出。
MOV  RAX, [rbp-0x8]   ; RAX <-- a