C语言编译执行过程
一、C語言的編譯執行過程
我們在C語言編輯的文件是以.c為文件拓展名的,稱為源文件;C語言編譯器的功能就是將源文件,經過編譯、鏈接之后可以形成可執行文件
那么具體的步驟是什么呢?
C源程序頭文件-->預編譯處理(cpp)-->編譯程序本身-->優化程序-->匯編程序-->鏈接程序-->可執行文件
二、編譯執行過程詳解
第一步:在編輯器中編輯源文件
第二步:編譯預處理;
預處理的作用就是讀取源文件中的字符流,對偽指令和特殊符號進行處理
預編譯程序的功能是將源文件中的特殊內容進行替換,但是不會改變源文件的含義,預編譯程序的輸出文件將作為下一步操作的原始文件
偽指令(以#開頭的指令)和特殊符號包括以下四種類型:
?1.宏定義指令:#define、#undef......#define Name *** 的功能是將源文件中的Name全部替換為***,而#undef的功能是取消某個宏的定義,使其不再生效
?2.條件定義指令:#ifdef、#ifndef、#endif等,這些偽指令的引入使得程序員可以通過定義不同的宏來決定編譯工具對哪些代碼進行處理,可以通過此方法過濾掉無用代碼
?3.頭文件包含指令:#include< >、#include" ",使用頭文件的目的是使得某些定義可以被多個源程序引用,預編譯程序將頭文件中的定義加入到其輸出文件中,以便編譯程序能夠對其進行處理;
?兩者的區別為#include< >引用的是系統提供的頭文件,而#include" "引用的為用戶自定義頭文件,其文件存放位置必須和源文件在同一路徑
?4.特殊符號:預編譯程序可以識別一些特殊符號,例如在源程序中出現的LINE標識將被解釋為當前行號(十進制數),FILE則被解釋為當前被編譯的C源程序的名稱
?
此外,在預處理階段,編譯器會刪除注釋內容,"//"和"/*"的內容,并且會添加代碼行號和文件標識,便于在后續過程中輸出報錯信息時定位到錯誤位置
第三步:編譯
經過預編譯程序的處理,其輸出文件將只包含變量。如數字、字符串、變量的定義,其工作就是將預編譯處理程序進行語法檢查和語句檢查,確認語句符合規范之后,將其翻譯為中間代碼或者匯編代碼
第四步:優化
優化是編譯程序中的重要部分,它涉及到的問題不僅包括編譯技術,還與機器的硬件環境有很大的關系
優化過程分為兩種:一是對中間代碼的優化,另一種是針對目標代碼進行的生成進行的優化
第一種優化的主要方式是刪除公共表達式以及循環優化,此方式不依賴計算機硬件平臺,主要包括代碼外提、強度削弱、變換循環控制條件、已知量的合并、復寫傳遞以及無用賦值的刪除
第二種優化則依賴硬件環境,最主要的問題是充分利用硬件的寄存器來保存有關變量的值,以減少內存訪問次數,此外,根據機器硬件的指令特點將代碼量減少以及增加代碼執行效率也是很重要的問題
經過優化的代碼必須經過匯編程序的匯編轉化為機器指令才能夠正常執行
第五步:匯編
匯編過程的主要功能是將匯編代碼轉化為機器指令,目標文件存放的就是和源文件相對應的機器指令
目標文件通常由段組成:數據段和代碼段
代碼段中包含的主要是程序的指令,一般文件權限是可讀可執行但不可寫
數據段中包含的主要是各種全局變量或靜態變量的數據,一般文件權限為可讀可寫可執行
?
匯編程序生成的是可重定位文件,其中包含了其它目標文件鏈接來創建一個可執行文件或共享的目標文件所需的代碼和數據
第六步:鏈接
?由匯編程序生成的目標文件并不能被直接執行,它可能還存在著許多的問題
?例如:某個源文件中的函數引用了另一個源文件中的內容,或者在程序中調用了函數庫中的函數,解決這些問題必須進行鏈接這一過程
?鏈接過程的主要功能是將有關目標文件相互連接,也就是將在某文件中對其它文件的引用與另一個文件中此引用的定義鏈接,使得這些目標文件能夠被操作系統裝入執行的整體
?根據開發人員同庫函數的鏈接方式的不同, 鏈接方式可分為:靜態鏈接和動態鏈接
- 靜態鏈接:在這種鏈接方式下,函數的代碼將從其所在地靜態鏈接庫中被拷貝到最終的可執行文件中,這樣該程序在執行時,相關代碼將被裝載到該進程的虛擬地址空間中。靜態鏈接庫實際上是一個目標文件的集合,其中每個文件含有庫中的一個或一組相關函數的代碼
- 動態鏈接:在這種鏈接方式下,函數的代碼被放到動態鏈接庫或共享對象的某個目標文件中。鏈接程序所做的就是在最終的可執行程序中記錄下共享對象的名字以及相關登記信息。在可執行文件運行時,動態鏈接庫中的所有內容都被映射到相應進程的虛地址空間中,可執行程序再根據相關登記信息找到相關執行代碼
?
經過上述過程,C源程序就轉化為了可執行程序,默認可執行程序的名字為a.out(Linux環境下)
三、編譯過程中的文件類型
- ? ? ? ?在Windows平臺上,C語言源代碼文件一般擴展名為.c,目標文件擴展名一般為.obj,生成的可執行文件擴展名一般為.exe
- 在Linux平臺上,C語言源代碼文件一般擴展名為.c,預處理操作后的文件名擴展名一般為.i,編譯器生成的匯編代碼一般擴展名為.s,生成的可執行文件一般擴展為.out,它是有匯編器生成的,所以默認gcc生成的程序名為a.out意思即為Assembler output
-
UNIX環境下主要有三種類型的目標文件:
(1)可重定位文件 其中包含有適合于其它目標文件鏈接來創建一個可執行的或者共享的目標文件的代碼和數據
(2)共享的目標文件 這種文件存放了適合于在兩種上下文里鏈接的代碼和數據。第一種事鏈接程序可把它與其它可重定位文件及共享的目標文件一起處理來創建另一個目標文件;第二種是動態鏈接程序將它與另一個可執行文件及其它的共享目標文件結合到一起,創建一個進程映象
(3)可執行文件 它包含了一個可以被操作系統創建一個進程來執行的文件
參考鏈接:http://lavasoft.blog.51cto.com/62575/187229
總結
- 上一篇: 这群猪,QQ群一共就15人,14个管理员
- 下一篇: 解决思科 Cisco Packet Tr