編譯系統和運行時的系統
編譯系統和運行時的系統(參照編譯原理第三版第11章)
源程序———預處理器———修改後的源程序——編譯器———匯編程序————匯編器————可重定位的目標程序————鏈接器(加入庫文件和可重定位的目標文件)————可執行的目標程序
大多數編譯系統提供一個驅動程序來調用預處理器、編譯器、匯編器、鏈接器、以支持用戶完成從源程序到可執行的目標文件。比如GCC。
如 gcc -v-o swap main.c swap.c
預處理器:
預處理器產生編譯器的輸入,主要有以下功能:
1.文件包含:
預處理器可以把源程序文件中的包含聲明(#include)展開為程序正文,#include<stdio.h>,系統會在標準路徑下搜素stdio.h,再用stdio.h中的內容代替這個語句。
2.宏展開
C程序可以用#define來定義宏,一個宏定義給出一段C代碼的縮寫,預處理器將源程序文件中出現的宏的引用展開相應的宏定義,稱為宏展開。
3.條件編譯
預處理器根據#if和#ifdef等編譯命令及其後的條件,將源程序中的某部分包含進來或排除在外,通常把排除在外的語句換成空行。
編譯器:
將C程序文件翻譯成
匯編器:
將匯編語言翻譯為機器語言的程序。一般而言,匯編生成的是目標代碼,需要經鏈接器(Linker)生成可執行代碼才可以執行。
最簡單的匯編器對輸入要進行兩次掃描,第一遍,匯編器掃描輸入,將表示存儲單元的所有標識符都存入符號表,並分配地址。
第二遍,匯編器再次掃描輸入,將每個操作碼都翻譯機器語言對應的位串,並將代表存儲單元的每個標識符翻譯成符號表中的為這個標識符分配的地址。
鏈接器:
1.可重定位的目標文件 它包含二進制代碼和數據,可以和其他可重定位目標文件組裝或一個可執行的目標文件。
2.可執行的目標文件
它包含二進制代碼和數據,可以直接被復制到內存並被執行。
(一)靜態鏈接庫與動態鏈接庫都是共享代碼的方式,如果采用靜態鏈接庫,lib中的指令都全部被直接包含在最終生成的exe文件中了。但是若使用dll動態鏈接庫,該dll不必被包含在最終的exe文件中,執行文件執行時可以動態地引用和卸載這個與exe獨立的dll文件(二)靜態鏈接庫不能再包含其他的動態鏈接庫或者靜態庫,而在動態鏈接庫中還可以再包含其他的動態或靜態鏈接庫。 使用差別靜態鏈接庫動態鏈接庫使用的區別在於它允許可執行模塊(dll或exe文件)僅包含在運行時定位dll函數的可執行代碼的所需信息。靜態鏈接庫的使用中,連接器從靜態鏈接庫獲取所有被引用的函數,並將庫同代碼一起放到可執行文件中。
編譯系統和運行時的系統