2010-10-26 68 views
8
$ gcc -O2 -S test.c -----------------------(1) 
     .file "test.c" 
    .globl accum 
     .bss 
     .align 4 
     .type accum, @object 
     .size accum, 4 
    accum: 
     .zero 4 
     .text 
     .p2align 2,,3 
    .globl sum 
     .type sum, @function 
    sum: 
     pushl %ebp 
     movl %esp, %ebp 
     movl 12(%ebp), %eax 
     addl 8(%ebp), %eax 
     addl %eax, accum 
     leave 
     ret 
     .size sum, .-sum 
     .p2align 2,,3 
    .globl main 
     .type main, @function 
    main: 
     pushl %ebp 
     movl %esp, %ebp 
     subl $8, %esp 
     andl $-16, %esp 
     subl $16, %esp 
     pushl $11 
     pushl $10 
     call sum 
     xorl %eax, %eax 
     leave 
     ret 
     .size main, .-main 
     .section .note.GNU-stack,"",@progbits 
     .ident "GCC: (GNU) 3.4.6 20060404 (Red Hat 3.4.6-9)" 

這是從這個C程序生成的彙編代碼:分析彙編代碼

#include <stdio.h> 
int accum = 0; 

int sum(int x,int y) 
{ 
    int t = x+y; 
    accum +=t; 
    return t; 
} 

int main(int argc,char *argv[]) 
{ 
    int i = 0,x=10,y=11; 
    i = sum(x,y); 
    return 0; 
} 

此外,這是由上述程序生成的目標代碼:

$objdump -d test.o -------------------------(2) 

test.o:  file format elf32-i386 

Disassembly of section .text: 

00000000 <sum>: 
    0: 55      push %ebp 
    1: 89 e5     mov %esp,%ebp 
    3: 8b 45 0c    mov 0xc(%ebp),%eax 
    6: 03 45 08    add 0x8(%ebp),%eax 
    9: 01 05 00 00 00 00  add %eax,0x0 
    f: c9      leave 
    10: c3      ret 
    11: 8d 76 00    lea 0x0(%esi),%esi 

00000014 <main>: 
    14: 55      push %ebp 
    15: 89 e5     mov %esp,%ebp 
    17: 83 ec 08    sub $0x8,%esp 
    1a: 83 e4 f0    and $0xfffffff0,%esp 
    1d: 83 ec 10    sub $0x10,%esp 
    20: 6a 0b     push $0xb 
    22: 6a 0a     push $0xa 
    24: e8 fc ff ff ff   call 25 <main+0x11> 
    29: 31 c0     xor %eax,%eax 
    2b: c9      leave 
    2c: c3      ret 

理想情況下,列表(1)和(2)必須相同。但我看到 在列表(1)中存在movl,pushl等,而mov,推入 lising(2)。我的問題是:

  1. 這是在處理器上實際執行的正確彙編指令嗎?
  2. 在上市(1),我看到這個開頭:

.file "test.c" 
    .globl accum 
     .bss 
     .align 4 
     .type accum, @object 
     .size accum, 4 
    accum: 
     .zero 4 
     .text 
     .p2align 2,,3 
    .globl sum 
     .type sum, @function 

,這在端:

.size main, .-main 
      .section .note.GNU-stack,"",@progbits 
      .ident "GCC: (GNU) 3.4.6 20060404 (Red Hat 3.4.6-9)" 

這是什麼意思?

謝謝。

回答

13

該指令被稱爲MOV無論使用什麼變體。後綴l只是一個gcc/AT & T程序集約定來指定所需的操作數的大小,在這種情況下是4個字節的操作數。

在Intel語法 - 其中存在任何歧義 - 而不是後面添加的指令,通常與所需要的大小的指標標記的存儲器的參數(例如​​,WORDDWORD等),這只是另一種方式達到同樣的目的。

89 55MOV從32位寄存器EBP到32位寄存器ESP的正確字節序列。上市沒有任何錯誤。


指定生成該彙編代碼的文件從:

.file "test.c" 

說該accum是一個全球性的符號(具有外部鏈接C變量):

.globl accum 

下列字節應放置在bss部分,這是一個在對象文件中不佔用空間但在運行時分配並歸零的部分。

 .bss 

對齊的4字節邊界上:

 .align 4 

它是一個對象(一個變量,而不是一些代碼):

 .type accum, @object 

這四個字節:

 .size accum, 4 

這裏是accum是定義了四個零字節。

accum: 
     .zero 4 

現在從bss部分切換到通常存儲函數的文本部分。

 .text 

最多可添加三個填充字節,以確保我們在一個4字節(2^2)邊界:

 .p2align 2,,3 

sum是一個全球性的象徵,它是一個函數。

.globl sum 
     .type sum, @function 

main大小是 「這裏」 - 「其中main開始」:

.size main, .-main 

這些已指定GCC堆棧特定的選項。通常,這是您選擇擁有可執行堆棧(不是非常安全)或不是(通常是首選)的地方。

 .section .note.GNU-stack,"",@progbits 

確定哪些版本生成該組件的編譯器:

 .ident "GCC: (GNU) 3.4.6 20060404 (Red Hat 3.4.6-9)" 
+0

+9,000。謝謝。關於GCC特定堆棧選項的一點很有幫助。 – kevinarpe 2015-02-13 04:31:27

0

彙編程序和反彙編列表顯示相同的代碼,但使用不同的語法。附加-l是gcc使用的語法變體。你在工具中有不同的語法(C編譯器輸出和反彙編)顯示你的工具鏈的弱點。

在總和偏移量11處可拆卸地顯示:僅顯示一些垃圾字節。進入下一個函數main的入口點是4字節對齊的,這會產生這種差距,填滿垃圾。

一堆.statements由彙編器的文檔定義。通常他們不提供任何可執行代碼。