看完這篇文章以後,終於明白了編譯到底怎麼回事。數據庫
對於同一個語句,有以下三種:高級語言、低級語言、機器語言的表示編程
C語言:windows
a=b+1;網絡
彙編語言:數據結構
mov -0xc(%ebp),%eax編輯器
add $0x1,%eax學習
mov %eax,-0x8(%ebp)spa
機器語言:操作系統
8b 45 f4翻譯
83 c0 01
89 45 f8
咱們都知道,機器是隻能作數字計算的,可以讓機器去運算的、數字的語言就是機器語言,除此以外的全部計算機語言都是非機器語言。
這樣的相對於機器語言的高級語言都須要一個轉換,從高級、機器不可理解,轉換爲機器可理解的機器語言。
這樣的一個轉換過程就叫作編譯(Compile),由編譯器(Compiler)來完成。
由C轉換爲彙編語言這一過程是由彙編器(Assembler)來執行的。
C和彙編語言轉換爲機器語言都是由編譯器來完成的。
這裏面,C是可跨平臺的,也能夠說是與平臺無關的。這裏的平臺有兩種說法,一種是指計算機的體系(Architecture),另外一種是指操做系統(Operate System),也能夠是指兩種的結合。
不一樣的平臺,他們所須要的執行機器語言的指令集是不一樣的。C的跨平臺性是指,只須要編寫一份不須要修改的C程序代碼,就能夠在不一樣體系、不一樣操做系統的計算機上運行。
這都要靠編譯器的功勞,編譯器將C程序翻譯爲了適合當前計算機體系的機器語言。
下面說一下將C語言編譯爲機器語言的整個過程:
首先,咱們寫出一份C程序代碼,命名該代碼爲hello.c,這個代碼文件,咱們稱之爲源代碼(Srouce Code)。
而後咱們運行編譯器,對該源代碼文件進行編譯,在整個編譯的過程當中,編譯器並不會執行該源代碼,只是生成一份新的機器語言代碼文件,如hello.out。
這份新生成的代碼文件稱爲目標代碼(Object Code)或可執行代碼(Executable)。
對於編譯過程,裏面還涉及到具體的一些能夠說的細節步驟。在Linux下,使用gcc編譯器:
❀ 預編譯hello.c文件:
gcc -E -o hello.i hello.c
執行成功後就會生成一個新的hello.i的文件,能夠用編輯器(Vim)查看它的內容,這個文件就是通過預編譯後的內容。
預編譯又稱爲預處理,是作些代碼文本的替換工做。預編譯能夠處理#開頭的指令,好比拷貝#include包含的文件代碼,#define的宏定義的替換,條件編譯等。
❀ 純粹的進行編譯:
gcc -S -o hello.s hello.i
把.i文件寫爲hello.c也行,就是跳過手動預編譯,直接完成預編譯和編譯兩個過程。
這時會獲得一個hello.s文件,打開看一下,裏面是編譯好的使用於當前體系結構的彙編代碼。
❀ 把彙編代碼處理爲目標文件:
gcc -c -o hello.o hello.s
把.s文件換成.c也行,就是自動完成預編譯、編譯和彙編三個過程。
如今獲得一個hello.o文件,這是一個二進制文件,但不是最後的可執行二進制文件,由於它還缺乏最後一步鏈接處理。
最後對目標文件.o文件進行鏈接,咱們這裏就一個.o文件因此簡單,常常是須要有多個.o文件須要鏈接。
❀ 鏈接執行:
gcc -o hello hello.o
若是把最後的.o文件寫成.c,那就和最開始咱們用hello.c編譯時示範的那樣了。實際上那樣是完成了預編譯、編譯、彙編和鏈接一連串的過程。
-o選項給輸出的文件從新命名而不使用gcc默認的文件名。
想了解更多gcc的姿式能夠到GNU上去看看。
最後,無論你是轉行也好,初學也罷,進階也可,若是你想學編程~
——【值得關注】個人 C/C++編程學習交流俱樂部!——
涉及:C語言、C++、windows編程、網絡編程、QT圖形界面開發、Linux編程、遊戲編程、數據結構與算以及數據庫......