通常我們使用gcc來生成可執行程式,命令為: gcc hello.c,預設生成可執行檔案a.out,其中經過下面幾個步驟:接下來將介紹每個步驟相應都做了那些工作編譯過程就是把預處理完的檔案進行一系列的詞法分析,語法分析,語義分析及優化後生成相應的彙編**。gcc -e hello.c -o hello.i
gcc –s hello.i –o hello.s
注:現在版本的gcc把預處理和編譯兩個步驟合成乙個步驟,用cc1工具來完成。gcc其實是後台程式的一些包裝,根據不同引數去呼叫其他的實際處理程式,比如:預編譯編譯程式cc1、彙編器as、聯結器ld。彙編器是將彙編**轉變成機器可以執行的命令,每乙個彙編語句幾乎都對應一條機器指令。彙編相對於編譯過程比較簡單,根據彙編指令和機器指令的對照表一一翻譯即可。通過呼叫鏈結器ld來鏈結程式執行需要的一大堆目標檔案,以及所依賴的其它庫檔案,最後生成可執行檔案。
ld -static crt1.o crti.o crtbegint.o hello.o -start-group -lgcc -lgcc_eh -lc-end-group crtend.o crtn.o (省略了檔案的路徑名)。
編譯過程可分為6步:掃瞄(詞法分析)、語法分析、語義分析、源**優化、**生成、目標**優化。詞法分析:掃瞄器(scanner)將源代的字串行分割成一系列的記號(token)。lex工具可實現詞法掃瞄。語法分析:語法分析器將記號(token)產生語法樹(syntax tree)。yacc工具可實現語法分析(yacc: yet another compiler compiler)。
語義分析:靜態語義(在編譯器可以確定的語義)、動態語義(只能在執行期才能確定的語義)。
源**優化:源**優化器(source code optimizer),將整個語法書轉化為中間**(intermediate code)(中間**是與目標機器和執行環境無關的)。中間**使得編譯器被分為前端和後端。編譯器前端負責產生機器無關的中間**;編譯器後端將中間**轉化為目標機器**。
目標**生成:**生成器(code generator).
目標**優化:目標**優化器(target code optimizer)。
鏈結的主要內容是把各個模組之間相互引用的部分處理好,使得各個模組之間能夠正確地銜接。鏈結的主要過程包括:位址和空間分配(address and storage allocation),符號決議(symbol resolution),重定位(relocation)等。鏈結分為靜態鏈結和動態鏈結。態鏈結是指在編譯階段直接把靜態庫加入到可執行檔案中去,這樣可執行檔案會比較大。而動態鏈結則是指鏈結階段僅僅只加入一些描述資訊,而程式執行時再從系統中把相應動態庫載入到記憶體中去。
關於 靜態鏈結和動態鏈結之間的差別可以看這篇部落格靜態庫和動態庫
C程式編譯過程
題記 前幾天去華為面試實習生,面試官問了個問題,讓我說出乙個程式的詳細編譯過程,當時磕磕絆絆說了一堆東西,事後自己都不知道當時說了什麼,慚愧。c語言編譯過程 編譯,編譯程式讀取源程式 字元流 對之進行詞法和語法的分析,將高階語言指令轉換為功能等效的彙編 再由匯程式設計序轉換為機器語言,並且按照作業系...
C 程式編譯過程
首先是編譯過程整體簡介 編譯過程主要分為 4個過程 1 編譯預處理 預編譯程式完成的工作,可以說成是對源程式的 替換 工作。經過這個過程,生成乙個沒有巨集定義 沒有條件編譯指令 沒有特殊符號的輸出檔案。2 編譯 優化階段 通過詞法分析 語法分析,在確認所有的指令都符合語法規則之後,將其翻譯成等價的中...
C程式編譯過程
gcc編譯c 會有四個階段 預處理 將c 中的標頭檔案和巨集進行處理 彙編 把彙編 轉化成機器指令,並以特定的二進位制格式輸出儲存在 o這樣的目標檔案中 流程圖 參考閱讀 3.c程式分析 gcc e hello.c o hello.i 預處理 gcc s hello.i o hello.s 編譯 g...