「hello,world」是各程式語言的開門語句,那我的第一篇就以「hello,world」為例來說明程式是如何執行的。
與書本保持一致,本系列文件的程式語言均為c語言。
本篇內容會分三個部分來介紹程式的執行過程,即,
計算機系統的硬體組成
程式的編寫和編譯
程式的執行
首先,我們來看一下乙個典型的計算機系統的硬體組成,如下,
接著,我們將逐一說明上圖涉及的硬體。
1)匯流排
2)i/o裝置
i/o裝置即輸入/輸出裝置,是系統與外部世界的聯絡通道。
以上圖示包含4個i/0裝置,
3)主儲存器
4)處理器
編寫程式的第一步當然是建立乙份包含源**的文字檔案,以列印「hello,world」為例,
#include int main()
我們通過編輯器建立並儲存以上內容,檔案命名為hello.c,該檔案即為源程式(或者說原始檔)。
在計算機系統中,源程式實際上是乙個由0和1組成的位序列(也成為位元序列),8個位構成一組,稱為「位元組」。乙個位元組則是上述源程式文字中的乙個字元。字元和位元組之間的對應關係即是我們常說的的ascii碼表。
在c語言中,原始檔無法被直接執行,需要被轉化成二進位制的可執行檔案才能行使它的功能,這個轉化過程就是我們所說的「編譯」。
unix系統中,從原始檔到可執行檔案的轉化是由gcc編譯器驅動程式完成的:
gcc -o hello hello.c
gcc讀取hello.c檔案內容,並把它翻譯成乙個可執行目標檔案hello。
該過程由四個階段構成:預處理器、編譯器、彙編器和鏈結器;該四個過程一起構成了編譯系統。
1) 預處理階段
預處理器cpp根據以字元#開頭的命令,修改原始的程式;
如我們的hello程式中#開頭語句為:#include ,cpp讀取該內容後會將系統標頭檔案studio.h的內容直接插入到hello.c中,繼而形成另乙個c程式,即hello.i(一般是以.i作為副檔名);
2) 編譯階段
編譯階段由編譯器ccl完成,ccl將文字檔案hello.i翻譯成文字檔案hello.s。
3) 彙編階段
彙編器as將hello.s翻譯成機器語言二進位制指令,並把這些內容打包成一種叫做可重定位目標程式的格式,結果儲存在hello.o中。
hello.o包含了main程式要執行的指令編碼。
4) 鏈結階段
鏈結器ld的作用是合併程式中用到的其他函式的指令,得到最終的可執行目標程式/檔案;如,
第二步中終於準備好了可執行檔案hello,該檔案可以被載入到記憶體中,由系統執行。
程式的執行分三步執行:
1) 系統從鍵盤讀取命令
使用者通過鍵盤在shell終端輸入」./hello」時(未按回車鍵),shell程式將字元逐一讀入暫存器,並將它放入快取中。
下圖黑色加粗線條展示了該過程的資料流向,藍色背景方框表示該過程涉及的硬體。
2) 系統從磁碟載入可執行檔案到記憶體
當我們在鍵盤上敲下回車鍵時,shell程式認為我們已經結束了命令的輸入;
緊接著,shell執行指令從磁碟儲存中讀取可執行檔案hello,將檔案中的**和資料從磁碟複製到記憶體。
3) 系統執行可執行檔案內容並輸出到終端顯示器
當可執行檔案hello中的**和資料被載入到記憶體,處理器開始執行程式中的main程式中的機器語言指令。
這些指令將」hello,world\n」字串中的位元組從記憶體複製到暫存器檔案,再從暫存器檔案複製到顯示裝置,最終在顯示屏上呈現」hello,world」字元。
注:文中均係本人在ppt中繪製;
那麼以上就是hello程式執行的實際過程,希望你看完這篇對自己程式的執行過程有了更深的印象和感受。
深入理解計算機系統
關鍵路徑是在迴圈的反覆執行中形成的資料相關鏈。迴圈展開是一種程式變換,通過增加每次迭代計算的元素的數量,減少迴圈的迭代次數。重新結合變換能夠減少計算中關鍵路徑上操作的數量,通過更好地利用功能單元的流水線能力得到更好的效能。浮點運算不保證是可結合的,通常迴圈展開和並行地累積在多個值中,是提高程式效能的...
《深入理解計算機系統》
知乎 深入理解計算機系統 這本書需要什麼水平能看懂?15 213 18 218 15 513 introduction to computer systems schedule fall 2016 鏈結失效則 cmu15 213的課程主頁,有ppt,還有錄影,主講人就是這本書的作者。備註 備註 詳細...
深入理解計算機系統
系統的硬體組成 快取記憶體 作業系統管理硬體 程序虛擬記憶體 檔案amdahl定律 併發和並行 0和1組成的位序列,又稱為位元序列,8個位被組織成一組,成為位元組。每個位元組表示程式中的某些文字字元。系統中的所有資訊 包括磁碟檔案 記憶體中的程式 記憶體中存放的的使用者資料以及網路上傳送的資料,都是...