排除这种ASM x86代码

问题描述:

首先的感觉,这里是汇编代码:排除这种ASM x86代码

/   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 
+0

您应该检查非调试代码 - 即不包含这些不必要存储的代码。 –

+0

编译器通常使用非常简单的规则将源代码拆分为一系列原始步骤(有时称为“中间代码”)。然后,它们优化中间代码以消除多余或浪费的步骤。您看起来已经关闭优化来编译此代码。 –

+0

您无需优化即可编译您的代码。毫不奇怪,当你告诉他们不要优化时,编译器会发出无用的怪异代码! – fuz

的线是独立的从对方:

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

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

从技术上讲,这两条线将是可选的,因为你可以写:

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

编辑:对于跳过此不必要的代码,你可以启用自动优化(海合会:-02)

+0

或者,不是从源代码中删除局部变量'a',程序员可以打开优化并让编译器执行它。从这个简单的例子可能不是很明显,但手动优化源代码通常会使其不易读,通常不如编译器那样有效。 –

+0

你是对的。我的例子应该只是说明为什么组装线出现。 – xanoetux

问题是你的反汇编程序被破坏了(或者至少“太聪明”),并且“有用地”给你提供了不同的,令人困惑的信息。以下两行:

|   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寄存器访问存储器间接。这样的内存被编译器用于局部变量,因此反汇编器显示的是“本地”。

+0

OP不问'local_8h是什么意思。 OP询问第二条指令的目的是什么,当它加载到'rax'中的值不可能与'rax'中已有的值不同时呢?答案是,因为这两行中的每一行都是从不同的源代码行生成的,并且关闭了优化。 –