2012-07-25 30 views
0

我在編譯中非常有趣,我有一個關於gcc的問題。如何執行代碼和gcc

我知道從代碼生成樹來編譯,然後ASM代碼是 生成,我需要一些關於這一點的解釋。

ASM代碼被添加到文件中並稍後執行或ASM代碼直接加載到內存中asm函數?我正在研究一個小型編譯器,並且我不知道如何執行生成的樹,而且我也沒有找到任何相關文檔。

+0

你想知道GCC如何做到這一點,或者你可以如何做到這一點? – harold 2012-07-25 17:18:23

+0

GCC如何做以及如何以最簡單的方式做到這一點。 – lilawood 2012-07-25 17:20:53

+0

請首先了解[彙編語言](http://en.wikipedia.org/wiki/Assembly_language)和[機器代碼](http://en.wikipedia.org/wiki/Machine_code)。這會幫助你提出更好的問題,甚至可以讓你自己回答。 – 2012-07-25 17:22:56

回答

2

GCC的前端解析不同語言的源文件(C,C++,Fortran,ObjectiveC,Java等)。然後將代碼(AST)轉換爲內部表示形式RTL (register transfer language)。這是一個貼近組裝的表示。

然後,將此RTL代碼轉換爲目標機器的程序集並寫入.o(對象)文件。

鏈接器然後將生成的.o文件組合到可執行文件。

GCC在C/C++中也支持「inline」彙編語言片斷。

工作流是

Source file -> 
AST -> 
    RTL representation -> 
    machine codes (with _optional_ text output of the ASM code) -> 
    Executable (produced by linker) 

對於解釋器也可直接解釋AST或產生你自己因爲這種解釋器(虛擬機)虛擬機的操作碼會比AST解釋簡單。

如果你想要所有的細節,你應該看看LCC (with a book by Chris Fraser and David Hanson)。附帶的書提供了所有關於真實世界架構代碼生成的細節。

要知道生成的代碼可以做什麼,你應該閱讀Linkers and Loaders by John Levine書。

最後,爲避免詢問關於腳本/口譯員的所有信息,請參閱Game Scripting Mastery by Alex Varanese

+0

GIMPLE和SSA在哪裏適合這張照片? – harold 2012-07-25 18:02:25

+0

SSA是優化和另一箇中間表示的工具。是的,這一切都適用於相同的工作流程。我剛剛省略了優化步驟。 – 2012-07-25 18:05:21

+0

我不太瞭解更新的GIMPLE(但它也是一個IR)。StackOverflow上有許多LLVM/Clang嫺熟操作人員,查找LLVM信息。與其他真實世界的項目一樣,它清晰明瞭,但「有點巨大」。 – 2012-07-25 18:08:08

2

模棱兩可的問題,我不認爲我完全明白你確切的問題是什麼,但無論如何你在這裏是一個答案:程序集沒有放在可執行文件中。彙編被寫入一箇中間彙編文件,彙編程序從該文件中生成真正的二進制機器代碼(稱爲對象文件),然後鏈接器將它們(連同所需的庫)合併到最終的可執行文件中。應用程序運行時,可執行文件由操作系統直接加載到RAM中,並由處理器本地執行。

+0

謝謝你。所以我必須將彙編代碼放在一個文件中,我想我必須使用__asm ___()來直接執行ASM。 – lilawood 2012-07-25 17:19:34

+0

@lilawood啊所以這就是你問的問題!不可以。您可以使用'__asm__' **指令**(它不是*函數),但它所做的只是告訴GCC逐個將其參數複製到生成的程序集文件中。 – 2012-07-25 17:24:51

+0

除非您在命令行中傳遞「-S」,否則GCC是否完全跳過「可讀的彙編代碼」階段? – harold 2012-07-25 17:28:07

1

源代碼如何轉換爲可執行代碼? 我們提供源代碼給編譯器,它給了我們可執行代碼。但這不是一步操作。這遵循一些預定義步驟將源代碼轉換爲可執行代碼。

步驟,遵循從源代碼轉換爲可執行代碼

1.Preprocessor 這是因爲它大量的工作之前,翻譯成機器代碼的編譯器非常有用的部分。它是一個文本處理器,其中包含以下文本編輯操作

它刪除源代碼中爲了更易讀易懂而編寫的源代碼中的註釋行。 它將頭文件的內容添加到源代碼中。頭文件總是包含函數原型和聲明(頭文件從不包含任何可執行代碼) 預處理器的一個非常重要的屬性是條件編譯。這對於可擴展設計非常必要。該屬性還可以消除編譯器不必要的負擔。 宏被這個預處理器替換。

這個階段的最終輸出被稱爲純C代碼。

2.翻譯器 這部分編譯器負責將純C代碼轉換爲彙編語言代碼。 將C語言代碼逐步映射到此處完成的彙編語言代碼。 本部分使用函數和聲明的原型來翻譯C代碼。 這個階段的輸出稱爲彙編代碼。

3.Assembler 它生成的彙編語言code.It的目標代碼的彙編語言代碼的機器語言代碼轉換(即0和1的格式)。它是不能直接運行的,因爲我們採取OS的幫助在處理器中執行我們的代碼。 這個階段的輸出稱爲目標代碼。

4.連接器 它給出了將在我們的機器上運行的最終可執行代碼。這個階段的輸出被稱爲可執行代碼。這是目標代碼和支持文件的組合。 支持文件可以是用戶定義的函數定義,預定義的庫函數定義等。