排除此 asm x86 代码的意义

Troubleshooting the sense of this asm x86 code

首先,这里是汇编代码:

/           0x000006a0      55             push rbp                             
|           0x000006a1      4889e5         mov rbp, rsp                         
|           0x000006a4      4883ec10       sub rsp, 0x10                        
|           0x000006a8      488d05b50000.  lea rax, str.AAAA           ; 0x764  

|           0x000006af      488945f8       mov qword [local_8h], rax  
|           0x000006b3      488b45f8       mov rax, qword [local_8h]

|           0x000006b7      4889c6         mov rsi, rax                         
|           0x000006ba      488d3da80000.  lea rdi, 0x00000769         ; "%s"   
|           0x000006c1      b800000000     mov eax, 0                           
|           0x000006c6      e895feffff     call sym.imp.printf         ;[2] ; i 
|           0x000006cb      b800000000     mov eax, 0                           
|           0x000006d0      c9             leave                                
\           0x000006d1      c3             ret  

到这个c程序:

#include <stdio.h>
#include <string.h>

int main(){

    char* a = "AAAA";

    printf("%s", a);
    return 0;
}

特别是我对这段代码有疑问:

|           0x000006af      488945f8       mov qword [local_8h], rax            
|           0x000006b3      488b45f8       mov rax, qword [local_8h]

这两条指令的意义是什么?我只以一种方式看到相同的指令,而不是相反。但这是为什么呢?

以下是有关可执行文件的更多信息:

blksz    0x0
block    0x100
fd       6
file     demo
format   elf64
iorw     false
mode     -r--
size     0x20e0
humansz  8.2K
type     DYN (Shared object file)
arch     x86
binsz    6559
bintype  elf
bits     64
canary   false
class    ELF64
crypto   false
endian   little
havecode true
intrp    /lib64/ld-linux-x86-64.so.2
lang     c
linenum  true
lsyms    true
machine  AMD x86-64 architecture
maxopsz  16
minopsz  1
nx       true
os       linux
pcalign  0
pic      true
relocs   true
relro    partial relro
rpath    NONE
static   false
stripped false
subsys   linux
va       true

这些行彼此分开:

第一行属于行char* a = "AAAA";,将变量的值保存到RAM。

第二行将printf("%s", a);行的RAM变量作为参数访问

从技术上讲,这两行都是可选的,就像您可以写的那样:

printf("%s", "AAAA");

编辑: 要跳过这些不必要的代码,您可以启用自动优化(对于 GCC:-O2)

问题是您的反汇编程序已损坏(或至少 "too smart")并且 "helpfully" 给您提供了与通常预期不同的、令人困惑的信息。这两行:

|           0x000006af      488945f8       mov qword [local_8h], rax            
|           0x000006b3      488b45f8       mov rax, qword [local_8h]

应该是

|           0x000006af      488945f8       mov qword [rbp-8h], rax            
|           0x000006b3      488b45f8       mov rax, qword [rbp-8h]

它们通过rbp寄存器间接访问堆栈帧中的内存。编译器将此类内存用于局部变量,因此反汇编程序显示的 "local"。