linux gcc編譯C程序

一個c語言程序從源文件到生成可執行文件,編譯器需要共經歷4個步驟:
1)預處理:把c文件中預處理命令掃描處理完畢,即對源代碼文件中的文件包含(#include)、預編譯語句(如宏定義#define等)進行分析,此時生成的文件仍然是可讀的。
2) 編譯:把預處理後的結果編譯成彙編或者目標模塊,即生成彙編語言文件,此時生成的文件仍然是可讀的彙編文件。
3)彙編:把編譯出來的結果彙編成具體CPU上的目標代碼模塊,也即此時轉換成具體的機器語言代碼,此時生成的文件是不可讀的非文本文件。
4)連接:把多個目標代碼模塊連接生成一個大的目標模塊,即將多個上面產生的機器代碼文件(與其它的機器代碼文件和庫文件)彙集成一個可執行的二進制代碼文件。

   gcc作爲c語言在linux下很著名的編譯軟件,分別有如下option來支持4個步驟:

  名稱 gcc選項 英文名稱        gcc調用的程序  示例
預處理 
-E      Pre-Processing  cpp           gcc -E test.c -o test.i
 
編譯 -S      Compiling       ccl           gcc -S test.i -o test.s 
 
彙編 -c       Assembling     as            gcc -c test.s -o test.o
 
連接 無       Linking        ld             gcctest.o -o test

說明:

  gcc在編譯c語言文件時,首先調用cpp進行預處理,在預處理過程中,對源代碼文件中的文件包含(#include)、預編譯語句(如宏定義#define等)進行分析;其次調用ccl進行編譯工作,將文件編譯成彙編語言文件,此時文件依舊是可讀的;之後調用as進行彙編工作,將具體的彙編語言文件編譯成cpu可執行的目標代碼,此時文件不可讀了;當所有的目標文件都生成之後,gcc就調用ld來完成最後的關鍵性工作,鏈接。在鏈接階段,所有的目標文件被安排在可執行程序中的恰當的位置,同時,該程序所調用到的庫函數也從各自所在的庫中鏈接到合適的地方。下面對上面4個過程做下分別的說明:

1、在預處理階段,如果不用“-o”指定文件名,那麼會默認將預處理結果輸出到標準終端設備。

[root@dbbak tmp]# cat a.c
int main()
{
       printf("shengtong test!\n");
}

[root@dbbak tmp]# gcc -E a.c
# 1 "a.c"
# 1 "<built-in>"
# 1 "<command line>"
# 1 "a.c"
int main()
{
       printf("shengtong test!\n");
}
[root@dbbak tmp]# gcc -E a.c -oa.i
[root@dbbak tmp]# cat a.i
# 1 "a.c"
# 1 "<built-in>"
# 1 "<command line>"
# 1 "a.c"
int main()
{
       printf("shengtong test!\n");
}

2、在編譯階段,如果不用“-o”指定文件名,那麼默認會生成一個“*.s”的彙編語言文件。

[root@dbbak tmp]# gcc -S a.i
[root@dbbak tmp]# ls
a.c  a.i 
a.s
[root@dbbaktmp]#
gcc -S a.i -oa1.s
[root@dbbak tmp]# ls
a.c  a.i  a.s a1.s

[root@dbbak tmp]#
[root@dbbak tmp]# cat a.s
       .file   "a.c"
       .section       .rodata
.LC0:
       .string "shengtong test!\n"
       .text
.globl main
       .type   main,@function
main:
       pushl   %ebp
       movl    %esp,%ebp
       subl    $8,%esp
       andl    $-16,%esp
       movl    $0,%eax
       subl    %eax,%esp
       subl    $12,%esp
       pushl   $.LC0
       call   printf
       addl    $16,%esp
       leave
       ret
.Lfe1:
       .size   main,.Lfe1-main
       .section       .note.GNU-stack,"",@progbits
       .ident  "GCC: (GNU) 3.2.3 20030502 (Red Hat Linux3.2.3-42)"
[root@dbbak tmp]# cat a1.s
       .file   "a.c"
       .section       .rodata
.LC0:
       .string "shengtong test!\n"
       .text
.globl main
       .type   main,@function
main:
       pushl   %ebp
       movl  

發佈了9 篇原創文章 · 獲贊 1 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章