看完这篇文章之后,终于明白了编译到底怎么回事
看完這篇文章之后,終于明白了編譯到底怎么回事。
1
對于同一個語句,有如下三種:高級語言、低級語言、機器語言的表示
C語言?
a=b+1;匯編語言?
mov -0xc(%ebp),%eax
add $0x1,%eax
mov %eax,-0x8(%ebp)機器語言?
8b 45 f4
83 c0 01
89 45 f8
我們都知道,機器是只能做數(shù)字計算的,能夠讓機器去運算的、數(shù)字的語言就是機器語言,除此之外的所有計算機語言都是非機器語言。這樣的相對于機器語言的高級語言都需要一個轉(zhuǎn)換,從高級、機器不可理解,轉(zhuǎn)換為機器可理解的機器語言。這樣的一個轉(zhuǎn)換過程就叫做編譯(Compile),由編譯器(Compiler)來完成。
由C轉(zhuǎn)換為匯編語言這一過程是由匯編器(Assembler)來執(zhí)行的。
C和匯編語言轉(zhuǎn)換為機器語言都是由編譯器來完成的。
2
這里面,C是可跨平臺的,也可以說是與平臺無關(guān)的。這里的平臺有兩種說法,一種是指計算機的體系(Architecture),另一種是指操作系統(tǒng)(Operate System),也可以是指兩種的結(jié)合。不同的平臺,他們所需要的執(zhí)行機器語言的指令集是不同的。C的跨平臺性是指,只需要編寫一份不需要修改的C程序代碼,就可以在不同體系、不同操作系統(tǒng)的計算機上運行。這都要靠編譯器的功勞,編譯器將C程序翻譯為了適合當前計算機體系的機器語言。
下面說一下將C語言編譯為機器語言的整個過程:
首先,我們寫出一份C程序代碼,命名該代碼為hello.c,這個代碼文件,我們稱之為源代碼(Srouce Code)。
然后我們運行編譯器,對該源代碼文件進行編譯,在整個編譯的過程中,編譯器并不會執(zhí)行該源代碼,只是生成一份新的機器語言代碼文件,如hello.out。這份新生成的代碼文件稱為目標代碼(Object Code)或可執(zhí)行代碼(Executable)。
3
對于編譯過程,里面還涉及到具體的一些可以說的細節(jié)步驟。
在Linux下,使用gcc編譯器:
預(yù)編譯hello.c文件:
gcc?-E -o hello.i hello.c執(zhí)行成功后就會生成一個新的hello.i的文件,可以用編輯器(Vim)查看它的內(nèi)容,這個文件就是經(jīng)過預(yù)編譯后的內(nèi)容。
預(yù)編譯又稱為預(yù)處理,是做些代碼文本的替換工作。預(yù)編譯可以處理#開頭的指令,比如拷貝#include包含的文件代碼,#define的宏定義的替換,條件編譯等。
純粹的進行編譯:
gcc?-S -o hello.s hello.i把.i文件寫為hello.c也行,就是跳過手動預(yù)編譯,直接完成預(yù)編譯和編譯兩個過程。這時會得到一個hello.s文件,打開看一下,里面是編譯好的使用于當前體系結(jié)構(gòu)的匯編代碼。
把匯編代碼進行匯編可執(zhí)行:
gcc?-c -o hello.o hello.s把.s文件換成.c也行,就是自動完成預(yù)編譯、編譯和匯編三個過程。現(xiàn)在得到一個hello.o文件,這是一個二進制文件,但不是最后的可執(zhí)行二進制文件,因為它還缺少最后一步連接處理。
最后對.o文件進行連接,我們這里就一個.o文件所以簡單,經(jīng)常是需要有多個.o文件需要連接。連接執(zhí)行:
gcc?-o hello hello.o如果把最后的.o文件寫成.c,那就和最開始我們用hello.c編譯時示范的那樣了。實際上那樣是完成了預(yù)編譯、編譯、匯編和連接一連串的過程。
想了解更多gcc的只是可以到GNU的網(wǎng)站上去看看。
BTW,gdb是常用的調(diào)式軟件。
總結(jié)
以上是生活随笔為你收集整理的看完这篇文章之后,终于明白了编译到底怎么回事的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Keil生成汇编文件、bin文件
- 下一篇: Matplotlib 快速入门