2012-02-11 52 views
8

我知道這是一個非常基本的問題,但是當我編譯我的C/C++代碼與GCC/G ++究竟是中間的輸出類型彙編進場之前生成機器碼?是不是像X86指令?GCC/G ++輸出型

+2

你的意思是什麼_intermediate_輸出? 'g ++'直接生成程序集。 – Lol4t0 2012-02-11 20:58:35

+0

以下選項可能會有用:'-g -Wa,-ahl = main.s'。它們導致GCC/G ++發出具有交錯高級源代碼的程序集。 – 2012-02-11 21:16:29

+0

這根本不是一個基本的問題。 – cha0site 2012-02-11 21:23:33

回答

12

GCC的處理鏈如下:

  • 源代碼

  • 預處理源代碼(擴展宏幷包含條註釋)(-E,.ii

  • 編譯爲程序集(-S.s

  • 組裝成二進制(-c.o

  • 鏈接到可執行

在每一個階段我已經列出了相關的編譯器標誌,使流程停在那裏以及相應的文件後綴。

如果使用-flto進行編譯,則將使用GIMPLE字節碼來修飾目標文件,GIMPLE字節碼是一種低級別中間格式,其目的是將實際的最終編譯延遲到鏈接階段,從而允許鏈接時間優化。

的「編譯」的階段適當的是實際的繁重的一部分。預處理器本質上是一個獨立的獨立工具(雖然它的行爲是由C和C++標準規定的),彙編器和連接器是非常獨立的獨立工具,它們基本上分別實現硬件的二進制指令格式和操作系統的可加載可執行格式。

+0

+1,優秀的答案。你可能想要添加一個關於什麼程序集的blurb,因爲看起來提問者並不完全清楚。 – cha0site 2012-02-11 21:24:47

+0

@ cha0site:謝謝...讓我們來看看; OP歡迎澄清,在這種情況下,我很樂意擴大。 – 2012-02-11 21:25:54

+0

@KerrekSB非常感謝您的詳細解答,我想我現在明白了。下面的ZarakiKenpachi回答也很有幫助。所以我猜gcc在生成程序集之前獲取有關我的硬件的信息,或者每種類型的硬件都有單獨的編譯器? – Cemre 2012-02-11 21:30:17

0

它必須是彙編代碼。您可以在命令行中使用-S標誌進行編譯。

0

沒有「中間輸出」。你得到的第一個輸出是機器碼。 (雖然可以通過調用預處理器與-E得到C/C++中間輸出。)

4

所以,在GCC可執行的彙編由4個部分組成:

1)預處理(GCC -E的main.c> main.i;變換的* .c爲* .I) 是否包括擴展,處理馬科斯。刪除評論。編譯(gcc -S main.i;如果成功,將* .i轉換爲* .s) 將C代碼編譯爲彙編器(在目標x86架構上,它是x86彙編,在目標x86_64架構上這是x64的組件,目標ARM架構是臂組件等) 這一部分中的大多數警告和錯誤的發生(如沒有錯誤和警告報告)

3)裝配(如main.s - o main.o;如果成功,則再次將* .i轉換爲* .o) 彙編生成彙編到機器碼。雖然還有程序的相對地址,諸如此類。

4.)鏈接(gcc main。o) 用絕對地址替換相對地址。刪除無用的文本。 在此階段鏈接錯誤和警告。 最後(如果成功),我們得到可執行文件。

所以,要回答你的問題,你所說的中間輸出實際上就是所謂的彙編語言 - 關於Assembly language wiki請參閱維基。

+0

非常感謝您的詳細解答。這非常有幫助。 – Cemre 2012-02-11 21:41:29

+0

第3步應閱讀「...將* .s轉換爲* .o」? – nickgrim 2012-02-12 00:23:18

0

GCC工具鏈,將程序從源代碼編譯到機器碼。編譯器生成彙編程序彙編到機器代碼中的彙編代碼。 Here是初學者的好教程。

2

這裏是由redhat magazine禮貌的GCC編譯步驟的圖形表示:

gcc compilation steps

相反,意味着什麼其他的答案,也沒有裝配步驟 - 相反,生成彙編代碼替換目標代碼的生成;如果您真正想要的是二進制表示,將內存中表示轉換爲文本表示並沒有什麼意義。

+0

嗯,是的,如果你打算編寫目標代碼,生成助記符是沒有什麼意義的,這些助記符是供人閱讀的。但是助記符與對象代碼幾乎是1:1,並且彙編器的代碼生成部分已完成(計算跳轉地址,諸如此類)。 – cha0site 2012-02-11 22:00:53