- 1.程式的環境
- 預編譯
- 1.頭檔案的包含
- 2.#define的預處理指令的執行
- 3.注釋的洗掉
- 編譯
- 匯編
- 鏈接
- 運行
1.程式的環境
寫過無數代碼的你是否想過你寫的.c檔案編譯鏈接運行形成.exe檔案的中間是怎樣執行的嗎?
從.c檔案到.exe檔案到代碼的執行,這就是程序,

.c檔案我們叫做源檔案,是文本檔案,.exe檔案是可執行檔案,是二進制檔案,是機器能夠讀懂的檔案,
在.c檔案編譯鏈接形成.exe檔案的環境我們成為編譯環境,.exe執行的環境我們稱為運行環境,
而編譯環境又可以分為編譯和鏈接兩個程序,而編譯程序又可以分為預編譯,編譯,匯編三個程序,

我們的代碼進行編譯所需要的工具是編譯器,例如VS2013等等編譯器,
我們每一個源檔案(.c),頭檔案(.h)都是通過編譯器(vs編譯器下的編譯器是cl.exe)單獨編譯生成目標檔案(.obj)最后通過聯結器(vs編譯器下的聯結器link.exe)形成可執行程式,這就是編譯的程序,我們接下來分為三個小步來具體決議編譯的程序,


當我們走到這里,我們用vs觀看就已經不再直觀,我們要使用Linux下的編譯環境用gcc編譯器觀看會更加的直觀,所以接下來的操作都是在Linux環境下進行操作的,如果對Linux編譯環境有興趣的,可以點擊下面一個鏈接能夠讓你輕松入門Linux,
Linux輕松入門
預編譯
1.頭檔案的包含

這是我們在Linux環境下寫的代碼,然后執行 gcc test.c -E -o test.i

執行后,代碼前面少了#include<stdio.h>,多了一大串其實的實際代碼,當我們把#include<stdio.h>去掉后再執行
gcc test.c -E -o test.i

可以清晰的看到代碼少了很多,
2.#define的預處理指令的執行
將#define定義的代碼直接替換掉

編譯之后的結果:

3.注釋的洗掉
我們進行的注釋在預編譯是直接洗掉掉的,

編譯之后的結果:

編譯
編譯的程序是將我們的C語言代碼編譯成了匯編代碼,
這其中包括:
1.詞法分析
2.語法分析
3.語意分析
4.符號匯總
這門課程叫做《編譯原理》有興趣的同學可以自己學習,
在Linux作業系統下的操作是
gcc test.i -S
這樣就會生成一個test.s的檔案

匯編
匯編就是把匯編代碼轉換成二進制指令(機器指令)
再一個就是形成符號表,
Linux下的操作是
gcc test.s -c
這樣就生成了一個test.o的二進制檔案
相當于是VS編譯下形成的test.obj 檔案
如圖是一段我們看不懂的指令,其實.obj檔案的格式是elf格式,在Linux下輸入指令readelf就能實作相應的操作,

鏈接
1.合并段表
Linux指令
readelf test.o -a

2.符號表的合并和重定向
就是每個檔案都有自己的符號表,合并和重定位就是將所有的符號匯總,例如在另外一個檔案宣告定義的函式,在這個檔案中使用,總體來說就是鏈接所有的檔案,
運行
- 程式必須載入記憶體中,在有作業系統的環境中:一般這個由作業系統完成,在獨立的環境中,程式
的載入必須由手工安排,也可能是通過可執行代碼置入只讀記憶體來完成, - 程式的執行便開始,接著便呼叫main函式,
- 開始執行程式代碼,這個時候程式將使用一個運行時堆疊(stack),存盤函式的區域變數和回傳
地址,程式同時也可以使用靜態(static)記憶體,存盤于靜態記憶體中的變數在程式的整個執行程序
一直保留他們的值, - 終止程式,正常終止main函式;也有可能是意外終止,
謝謝大家!!!!!
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/353392.html
標籤:其他
