C編譯鏈接——從代碼到可執行程序的蛻變之路

       計算機其實是比較笨的,它能夠識別的只有01序列。也許有人說,不會啊,明明計算機可以幫助我們做很多事情的呀。
       這就要說到計算機行業必不可少的職業:程序員。
       其實我們通常使用計算機來瀏覽網頁、玩遊戲等等功能的實現,都離不開程序員手裏的代碼。舉個例子,比如很多人都玩過的電腦小遊戲——掃雷。對於計算機使用者來說,只需要打開界面,就可以開始遊戲了。而對於程序員來說,首先要分析這個遊戲的邏輯關係以及它的玩法,分析清楚之後,使用編譯器來編寫實現這個遊戲的代碼,然後在編譯器環境下,編譯鏈接生成可執行程序——也就是計算機能夠識別的01序列,再經過後期界面設計等環節,掃雷遊戲就可以投入使用了。那麼,從源代碼到計算機能夠識別的01序列階段,到底發生了什麼樣的進化呢?
       我們上課時,常常聽到老師講“我們以前學習編代碼的時候,都是在紙帶打點,根據有點沒點來判斷是0是1 ”。隨着計算機的更新換代,也有老師說“我們當時學習編代碼的時候,都是彙編指令操作”。到現在,我們使用的都是C語言等高級語言,所謂高級語言,就是計算機替我們做了從源代碼到01序列的轉化。
       下面我們來看一下詳細的轉化過程:
       1. 預處理。即預編譯,在預處理過程中,主要實現宏替換、去註釋、頭文件展開以及條件編譯的功能。
       我們先來看一個簡單的C代碼:

<span style="font-size:24px;">#include<stdio.h>
#define DEBUG 
#define M 5
int main()
{
	int num = 5;
#ifdef DEBUG    //條件編譯
	printf("%d  %d\n", M, num);
#endif
	return 0;
}</span>

       這個代碼中,<stdio.h>是頭文件,其次,定義了兩個宏,其中宏DEBUG沒有賦值。接着,#ifdef是條件編譯,以#endif結尾,意思是,如果宏DEBUG被定義,那麼打印printf函數裏的內容。//是註釋。我們來在CenTOS環境下看一下預編譯後的程序:

                                   


       在這裏,大家可以看到,與源代碼相比,頭文件被展開;由於宏DEBUG被定義,所以條件編譯執行;而代碼中的宏M被5所替換,這就是宏替換;原先在代碼中的註釋也被去掉了。
       2. 編譯。源代碼經過解析,判斷它的語句的意思。在這個階段產生絕⼤多數的錯
誤和警告
。然後程序被翻譯成彙編代碼,再到目標代碼(這裏目標代碼顯示爲16進制)。下面是彙編代碼和目標代碼:

                                              
                                              
 

     3. 鏈接。每個目標文件代碼經過鏈接捆綁在⼀起,形成⼀個單⼀而完整的
可執行程序。同時,鏈接器也會引入標準
C函數庫中任何被該程序所用到的函數,而且它
可以搜索程序員個人的程序庫,將其需要的函數也鏈接到程序中。在這個程序中,只有一個目標文件,C函數庫中要用到的函數是printf。

                


              上圖就是鏈接後生成的完整可執行程序的16進制序列。
       上面三個過程我們一般統稱爲源代碼的翻譯過程。但是我們編寫代碼的目的並不是要翻譯他,而是要讓他來達到我們使用的目的,那麼就需要運行的結果,所以除此之後,還有一個執行過程。
       執行過程大致分爲以下四步:
       1.程序載入內存。在馮諾依曼體系結構當中,計算機被分爲五大構件,即輸入、輸出,存儲器、運算器和控制器,其中運算器和控制器是CPU的核心部件。各部件運作關係如下圖:
       大家可以看到,輸入單元寫入內容後必然要先載入內存,然後傳到CPU,經過CPU處理後再次傳入內存進行輸出,也就是說,內存是連接輸入輸出的一個橋樑。我們使用的編譯器相當於輸入單元,那麼同樣的,代碼必須先載入內存,才能進行處理運算輸出。在有操作系統的環境中:⼀般這個由操作系統完成。在獨立的環境中,程序的載入必須由手工安排,也可能是通過可執行代碼置入只讀內存來完成。
       2.程序開始執行。接着便調用main函數。
       3.開始執行程序代碼。這個時候程序將使用一個運行時堆棧(stack),存儲函數的局部變量和返回地址。程序同時也可以使用靜態(static)內存,存儲於靜態內存中的變量在程序的整個執行過程⼀直保留他們的值。
       4.終止程序。正常終止main函數;也有可能是意外終止。



       如有錯誤,歡迎指出,一起交流學習!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章