深入理解計算機系統之三 C程式編碼

2021-10-21 15:43:02 字數 2223 閱讀 5276

假設有乙個hello.c程式,**如下:

#include int main()

我們在unix系統中編譯

gcc -o hello hello.c
編譯後執行./hello,就能看到結果了。

當我們在系統上編譯hello程式時,系統做了些什麼?

hello程式的生命週期是從乙個高階c語言程式開始的,因為這種形式能夠被人讀懂。然而,為了在系統上執行hello.c程式,每條c語句都必須被其他程式轉化為一系列的低階機器語言指令。然後這些指令按照一種稱為可執行目標程式的格式打好包,並以二進位制磁碟檔案的形式存放起來。目標程式也稱為可執行目標檔案。

unix系統上,從原始檔到目標檔案的轉化是由編譯器驅動程式完成的:

在這裡, gcc編譯器驅動程式讀取源程式檔案hello.c,並把它翻譯成乙個可執行目標檔案hello。這個翻譯過程可分為四個階段完成,如圖所示。執行這四個階段的程式(預處理器、編譯器 、彙編器和鏈結器)一起構成了編譯系統(compilation system)。

預處理階段:預處理器(cpp)根據以字元#開頭的命令,修改原始的c程式。比如hello.c中第1行的#include命令告 訴預處理器讀取系統標頭檔案stdio.h的內容,並把它直接插入 程式文字中。結果就得到了另乙個c程式,通常是以.i作為副檔名。

編譯階段:編譯器(ccl) 將文字檔案hello.i翻譯成文字檔案hello.s,它包含乙個組合語言程式。該程式包含函式main的定義。

在命令列上使用「-s」選項,就能看到c語言編譯器產生的彙編**,這會使gcc執行編譯器,產生乙個彙編檔案hello.s,但是不做其他進一步的工作。

彙編階段:接下來,彙編器(as)將hello.s翻譯成機器語言指令,把這些指令打包成一種叫做可重定位目標程式 (relocatable object program) 的格式,並將結果儲存在目標檔案hello.o中。hello.o檔案是乙個二進位制檔案,它包含的 17個位元組是函式main的指令編碼。如果我們在文字編輯器中開啟hello.o檔案,將看到一堆亂碼。

如果我們使用 「-c」 命令列選項,gcc會編譯並彙編該**:這就會產生目標**檔案hello.o, 它是二進位制格式的,所以無法直接檢視。

linux系統中,帶 『-d』 命令列標誌的程式objdump(表示 「object dump」)可以充當這個角色:

鏈結階段:請注意,hello程式呼叫了printf函式,它是每個c編譯器都提供的標準c庫中的乙個函式。printf函式存在於乙個名為printf.o的單獨的預編譯好了的目標檔案中,而這個檔案必須以某種方式合併到我們的hello.o程式中。鏈結器(id)就負責處理這種合併。結果就得到hello檔案,它是乙個可執行目標檔案(或者簡稱為可執行檔案),可以被載入到記憶體中,由系統執行。

gcc -o hello hello.c

深入理解計算機系統

關鍵路徑是在迴圈的反覆執行中形成的資料相關鏈。迴圈展開是一種程式變換,通過增加每次迭代計算的元素的數量,減少迴圈的迭代次數。重新結合變換能夠減少計算中關鍵路徑上操作的數量,通過更好地利用功能單元的流水線能力得到更好的效能。浮點運算不保證是可結合的,通常迴圈展開和並行地累積在多個值中,是提高程式效能的...

《深入理解計算機系統》

知乎 深入理解計算機系統 這本書需要什麼水平能看懂?15 213 18 218 15 513 introduction to computer systems schedule fall 2016 鏈結失效則 cmu15 213的課程主頁,有ppt,還有錄影,主講人就是這本書的作者。備註 備註 詳細...

深入理解計算機系統

系統的硬體組成 快取記憶體 作業系統管理硬體 程序虛擬記憶體 檔案amdahl定律 併發和並行 0和1組成的位序列,又稱為位元序列,8個位被組織成一組,成為位元組。每個位元組表示程式中的某些文字字元。系統中的所有資訊 包括磁碟檔案 記憶體中的程式 記憶體中存放的的使用者資料以及網路上傳送的資料,都是...