Linux中GCC编译C程序过程,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              gcc test.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 ""

# 1 ""

# 1 "a.c"

int main()

{

printf("shengtong test!\n");

}

[root@dbbak tmp]# gcc -E a.c -o a.i

[root@dbbak tmp]# cat a.i

# 1 "a.c"

# 1 ""

# 1 ""

# 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@dbbak tmp]# gcc -S a.i -o a1.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 Linux 3.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    %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 Linux 3.2.3-42)"

3、在汇编阶段,如果不用“-o”指定文件名,那么默认会生成一个“*.o”的机器语言代码文件。

[root@dbbak tmp]# gcc -c a.s

[root@dbbak tmp]# ls

a.c a.i a.o a.s a1.s

[root@dbbak tmp]# gcc -c a1.s -o a1.o

[root@dbbak tmp]# ls

a.c a.i a.o a.s a1.o a1.s

[root@dbbak tmp]#

[root@dbbak tmp]# file a.o

a.o: ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), not stripped

[root@dbbak tmp]# file a1.o

a1.o: ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), not stripped0b1331709591d260c1c78e86d0c51c18.png

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值