【C語言】編譯連結的詳細過程
阿新 • • 發佈:2019-02-10
相信大家在學習C語言時,肯定會有這麼一個問題,計算機把一段程式轉化為能識別的二進位制機器語言的過程是什麼?
大體的來講需要經歷四個過程:預處理,編譯,彙編,連結。接下來我會給大家一一說明。
首先預處理過程所做的操作是 進行程式的巨集替換,去註釋,標頭檔案按照路徑展開,以及條件編譯。
接著編譯操作完成把C語言轉成組合語言。
再接下來,彙編操作完成把組合語言轉化成二進位制語言(半成品)
最後,連結操作引入庫檔案,生成可執行的二進位制程式碼。
為了進一步的體現這些過程,我們在linux系統下,通過指令來完成,讓大家看的更明白。
首先預處理完成預替換、去註釋、標頭檔案按照路徑展開、以及條件編譯。
我們建立一個zuoye.c檔案。裡面寫入註釋、巨集定義、標頭檔案、條件編譯。
如下圖:
使用的gcc命令是:gcc –E zuoye.c -o zuoye.i gcc -E的作用是將.c檔案轉化成.i檔案,可以在預處理之後就停下來。 我們可以通過這條指令觀察預處理以後程式的情況。 zuoye.i裡包含的是預處理以後停下來的那個程式碼。 如下圖: 此時我們發現巨集定義已被替換,而註釋也已經被刪除,標頭檔案展開了,條件編譯也執行了。 那麼接下來需要進行編譯操作了。 使用的gcc命令是:gcc –S zuoye.i -o zuoye.s gcc -S的作用是將.i檔案轉化成.s檔案,可以在編譯完成之後,彙編開始前停下來。 我們可以通過這條指令觀察編譯以後的情況。 zuoye.s裡包含的是編譯完成後,彙編開始前停下來的那個程式碼。 如下圖:
此時我們發現,編譯的這個操作已經把C語言轉化為組合語言了。
緊接著需要進行彙編操作。
使用的gcc命令是:gcc –C zuoye.s -o zuoye.o
gcc -S的作用是將.s檔案轉化成.o檔案,可以在彙編完成後,連結開始前停下來。
我們可以通過這條指令觀察彙編以後的情況。
zuoye.o裡包含的是彙編完成後,連結開始前停下來的那個程式碼。
如下圖:
通過上圖,我們可以發現彙編實際上指把組合語言程式碼翻譯成目標機器指令的過程。
對於被翻譯系統處理的每一個C語言源程式,都將最終經過這一處理而得到相應的目標檔案。
目標檔案中所存放的也就是與源程式等效的目標的機器語言程式碼。
彙編程式生成的目標檔案實際上是可重定位檔案,它其中包含有適合於其它目標檔案連結來建立一個可執行的或者共享的目標檔案的程式碼和資料。 也就是說,由彙編程式生成的目標檔案並不能立即就被執行,它並非最終可執行的二進位制序列,因為其中可能還有許多沒有解決的問題。那麼這個就是連結程式的工作了。
所以最後為了生成可執行程式,我們需要連結。 使用的gcc命令是:gcc zuoye.o -o mytest 作用是將.o檔案轉化成可執行程式。 如下圖:
這樣就得到了計算機能夠讀的二進位制序列了。
使用的gcc命令是:gcc –E zuoye.c -o zuoye.i gcc -E的作用是將.c檔案轉化成.i檔案,可以在預處理之後就停下來。 我們可以通過這條指令觀察預處理以後程式的情況。 zuoye.i裡包含的是預處理以後停下來的那個程式碼。 如下圖: 此時我們發現巨集定義已被替換,而註釋也已經被刪除,標頭檔案展開了,條件編譯也執行了。 那麼接下來需要進行編譯操作了。 使用的gcc命令是:gcc –S zuoye.i -o zuoye.s gcc -S的作用是將.i檔案轉化成.s檔案,可以在編譯完成之後,彙編開始前停下來。 我們可以通過這條指令觀察編譯以後的情況。 zuoye.s裡包含的是編譯完成後,彙編開始前停下來的那個程式碼。 如下圖:
彙編程式生成的目標檔案實際上是可重定位檔案,它其中包含有適合於其它目標檔案連結來建立一個可執行的或者共享的目標檔案的程式碼和資料。 也就是說,由彙編程式生成的目標檔案並不能立即就被執行,它並非最終可執行的二進位制序列,因為其中可能還有許多沒有解決的問題。那麼這個就是連結程式的工作了。
所以最後為了生成可執行程式,我們需要連結。 使用的gcc命令是:gcc zuoye.o -o mytest 作用是將.o檔案轉化成可執行程式。 如下圖: