先從乙個最簡單的案例入手 helloworld.c,這裡我就不寫了,大家都寫過,我把它編譯成可執行程式gcc -o helloworld helloworld.c
預處理:將所有的巨集定義替換、#include檔案展開、刪除所有的注釋、新增行號和檔名標示、當然還有保留#pragma編譯指令等
編譯:把檔案進行語法分析、詞法語義分析後編譯成彙編
彙編:彙編成機器碼,這個沒有什麼好說的,此案例中彙編成目標檔案 helloworld.o
鏈結:鏈結通常是乙個讓人很費解的過程,這裡很難一言道盡,這個也是我後面研究和說明的重點,簡單的可以認為是把各個目標檔案同系統庫檔案合併成乙個可執行程式、或是靜態或動態庫
幾點說明;
1、通常說的編譯包括預處理、編譯、彙編
2. 編譯可以分為前段和後端處理兩個部分,前段就是預處理和編譯,它是與機器無關的操作,負責生成機器無關的中間**;後端是機器相關操作,將中間**生成目標機器代 碼
3. 優化有多層優化,前段的是**級優化、後端是目標**優化
先撇開鏈結不談,編譯之後的目標檔案helloworld.o到底是什麼檔案,它包括哪些內容,在linux中它是elf檔案,當然linux中可執行檔案、庫等都是elf檔案,windows下的檔案格式這裡不做討論,有興趣的同學可以自己研究。這裡重點講的事目標檔案到底包含什麼內容:
目標檔案中含有很多「段」,平時我們口上所說的**段、data段、bss段等都在它裡面,總結一下它大致包含一下幾個重要的段
.text (**段) .data(資料段) .bss(為初始資料段) .strtab(字串相關) .shstrtab(段相關) .symtab(符號表)
這裡我就不對各個段做詳細的描述、那我們是如何解析、裝載乙個elf檔案了,其實每個elf檔案都有乙個elf檔案頭,檔案頭記錄了段資訊的入口,這樣我們就可以通過此入口遍歷所有的段
幾點說明:
2. bss這個段其實很多編譯器有優化,未初始話的變數預設為0,所以它實際沒有儲存value
3. 符號變是乙個很重要的段,後面章節鏈結主要是用到它
靜態鏈結 編譯和鏈結(一)
彙編鏈結 小結本文主要是 程式設計師的自我修養 一書的內容摘要和梳理,如有需要並且沒有被本文涵蓋的內容,建議讀者自行 原書。靜態鏈結 目標檔案 二 靜態鏈結 靜態鏈結 三 裝載與動態鏈結 裝載與程序 一 裝載與動態鏈結 動態鏈結 二 本部分主要是介紹關於程式源 是如何到可執行檔案的,及這其中涉及到的...
編譯和鏈結
一般來說,無論是c c 首先要把原始檔編譯成中間 檔案,在windows下也就是 obj 檔案,unix下是 o 檔案,即 object file,這個動作叫做編譯 compile 然後再把大量的object file合成執行檔案,這個動作叫作鏈結 link 編譯時,編譯器需要的是語法的正確,函式與...
編譯和鏈結
在多道程式的實現中,要想使原始檔生成可執行檔案通常需要兩個步驟編譯和鏈結,其中編譯是指將原始檔編譯為中間 檔案,在linux中為 o檔案,其實質就是由c或c 等高階語言生成組合語言。生成可執行檔案,我們以編譯c c 為例,在windows中編譯生成的為.obj檔案,在linux unix中生成.o檔...