(文章目錄)
一、程式的翻譯環境(編譯和連結)
在ANSI C 的任何一種實作中,存在兩個不同的環境:
- 第一種是翻譯環境,在這個環境中源代碼被轉換成可執行的機器指令。
- 第二種是執行環境,它用于實際執行代碼。
- 組成一個程式的每個源檔案(test.c)通過編譯過程分别轉換成目标代碼(test.obj)
- 每個目标檔案又由連結器(linker)捆綁在一起,形成一個單一而完整的可執行程式。
- 連結器同時會引入标準c函數庫中任何被該程式所用到的函數。
-
預編譯 (預處理)(test.c --->test.i)
(1)處理所有的注釋,以空格代替
(2)将所有的#define删除,并展開所有的宏定義
(3)處理條件編譯指令#if、#ifdef、#elif、#else、#endif
(4)處理#include,展開被包含的檔案
(5)保留編譯器需要使用的#pragma指令
-
編譯 (test.i --->test.s)
(1)把C語言代碼編譯成彙編代碼
(2)進行文法分析,詞法分析,語義分析,符号彙總形成符号表
-
彙編 (test.s --->test.o)
彙編過程實際上指把彙編語言代碼翻譯成目标機器指令的過程。對于被翻譯系統處理的每個C語言源程式,都将最終經過這一處理而得到相應的目标檔案。 目标檔案中所存放的也就是與源程式等效的目标的機器語言代碼。
- 合并段表
- 符号表的合并和符号表的重定位
- 最後形成(test.exe)
二、程式的運作環境
- 程式必須載入記憶體,在有作業系統的環境中:一般這個由作業系統來完成。在獨立的環境中,程式的載入必須由手工安排,也可能是通過可執行代碼置入隻讀記憶體來完成。
- 程式的執行便開始,接着調用main函數。
- 開始執行程式代碼,這個時候程式将使用一個運作時堆棧,存儲函數的局部變量和傳回位址,程式同時也使用靜态(static)記憶體,存儲與靜态記憶體中的變量在程式的整個執行過程一直保留他們的值。
- 終止程式。正常終止main函數,也可能是意外終止(代碼出錯)