2017-05-31 124 views
1

首先的感覺,這裏是彙編代碼:排除這種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

回答

2

的線是獨立的從對方:

第一行屬於線char* a = "AAAA";,保存可變到RAM的值。

第二行從RAM訪問變量printf("%s", a);作爲參數。

從技術上講,這兩條線將是可選的,因爲你可以寫:

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

編輯:對於跳過此不必要的代碼,你可以啓用自動優化(海合會:-02)

+0

或者,不是從源代碼中刪除局部變量'a',程序員可以打開優化並讓編譯器執行它。從這個簡單的例子可能不是很明顯,但手動優化源代碼通常會使其不易讀,通常不如編譯器那樣有效。 –

+0

你是對的。我的例子應該只是說明爲什麼組裝線出現。 – xanoetux

0

問題是你的反彙編程序被破壞了(或者至少「太聰明」),並且「有用地」給你提供了不同的,令人困惑的信息。以下兩行:

|   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'中已有的值不同時呢?答案是,因爲這兩行中的每一行都是從不同的源代碼行生成的,並且關閉了優化。 –