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万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章