gcc编译器的整个工作过程
gcc hello.c?? ./a.out???? 或者 gcc hello.c -o hello?? ./hello
./表示執行當前目錄下的可執行程序或腳本程序。
首先gcc需要調用預處理程序cpp,由它負責展開在源文件中定義的宏,并向其中插入“#include”語句所包含的內容;接著gcc會調用編譯程序ccl和匯編程序as將處理后的源代碼編譯成目標代碼;最后,gcc會調用鏈接程序ld,把生成的目標代碼鏈接成一個可執行程序。其實gcc本身只是做了編譯這一項工作,其余階段的工作都是gcc調用其余服務程序來完成的。
預處理階段。gcc把預處理命令掃描處理完畢,輸入C語言的源文件(.c),這個階段主要處理源文件中的#ifdef、#include、#define等預處理命令,該階段會生成一個中間文件.i。可以使用-E參數讓gcc在預處理階段結束后停止編譯過程,從而生成經過預處理的C源代碼文件:gcc -E hello.c –o hello.i? vim hello.i? //查看該文件實際的變化? ? ? 該階段詳細情況舉例說明說明如下:
//head.h #ifndef __HEAD_H__ #define __HEAD_H__#define NUM1 10 #define NUM2 20 #endif//sum.c #include <stdio.h> //直接在標準庫中查找 #include "head.h" //先在工作目錄中查找,找不到再去標準庫中查找 #define DEBUG //去掉這一行,gcc編譯時采用-D參數即可,生成最終文件時,不用-D參數。 int main(void) {int a = NUM1;int aa;int b = NUM2;int sum = a + b;// 小盆友: 這是一個加法運算 #ifdef DEBUGprintf("The sum value is: %d + %d = %d\n", a, b, sum); #endifreturn 0; }如上段代碼中,有兩個文件,一個頭文件head.h和一個c語言源代碼文件sum.c。執行gcc -E sum.c -o sum.i后,打開sum.c可以看到如下內容:
//這上面還有很多內容,全是stdio.h頭文件的內容 extern int ftrylockfile (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) ;extern void funlockfile (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)); # 943 "/usr/include/stdio.h" 3 4# 2 "sum.c" 2 # 1 "head.h" 1 # 3 "sum.c" 2int main(void) {int a = 10;int aa;int b = 20;int sum = a + b;return 0; }可以看到在預處理過程中,預處理程序主要做了以下幾件事情:1.處理#include,將所有頭文件的內容都全部包含進來;2.處理掉所有的條件預編譯命令,#ifdef? ?#ifndef? #endif等;3.刪除所有的#define,并且展開所有的宏定義,即字符替換;4.刪除所有注釋;5.添加行號和文件標識,這樣在調試和編譯出錯時才知道是哪個文件哪一行的問題;5.保留#pragma編譯器指令,因為編譯器在編譯過程中需要使用它們。
#pragma para(其中para為參數)編譯器指令的作用是設定編譯器的狀態或者是指示編譯器完成一些特定的動作。#pragma 指令對每個編譯器給出了一個方法,在保持與C 和C ++語言完全兼容的情況下,給出主機或操作系統專有的特征。依據定義,編譯指示是機器或操作系統專有的,且對于每個編譯器都是不同的。
編譯階段。gcc把預處理后的結果編譯成匯編語言代碼,輸入的是.i,編譯后生成匯編語言文件.s:gcc -S hello.i –o hello.s ?vim hello.s? ? hello.s為匯編語言代碼(沒學過匯編的表示也看不懂!!)
匯編階段。編譯器把編譯出來的匯編語言匯編成具體CPU上的目標代碼(機器代碼)。輸入匯編代碼文件.s,輸出目標代碼文件.o或.obj:gcc –c hello.s –o hello.o? vim hello.o? .o文件也是一個二進制代碼文件,只是還不能執行,需要進行鏈接。
鏈接階段。把多個目標代碼模塊鏈接成一個大的目標代碼模塊。輸入目標代碼文件.0(與其它的目標代碼文件、庫文件、引導代碼),匯集成一個可執行的二進制代碼文件:? gcc hello.o –o hello? vim hello? ? ? ?執行: ./hello? ??
后續(操作系統范疇):機器代碼hello在操作系統機器上解釋操作系統的;然后在機器語言機器上被翻譯稱為一個個微程序;最后,微程序的每一條微指令在微指令系統上執行。
總結
以上是生活随笔為你收集整理的gcc编译器的整个工作过程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: gcc与g++编译器
- 下一篇: 宏定义对调试代码的作用