分享

C语言编译过程

 昵称14561204 2014-02-23

现在我们看一下C 的编译过程..

预编译,编译生成汇编,汇编生成目标文件,目标文件连接库文件生成可执行文件,这个过程人人都知道,但是究竟如何呢?

牢骚一下:太多的编译器都是一步到位,其实这对学习不是什么好事情,至少我觉得,在学习过程中把简单的东西弄的麻烦,在工作的过程中把麻烦的东西弄的简单。

这里的例子选自 lorne

预编译 gcc -E

编译 gcc -S 这两个有gcc rpm包就可以。

汇编as

连接ld 这两个需要安装binutils rpm包

1,预编译

编写c源程序game.c

#include

int main()

{

printf("Hello World!\n");

} 传说中的helloworld

gcc -E -o pregame game.c

这是会出现一个pregame文件

看看他是什么格式

file pregame

pregame: ASCII C program text

也就说预编译之后的文件仍然是c源代码。那么预编译作了些什么呢?

可以看看都有些什么玩意.

cat pregame

你会发现 pregame和game 差不多,区别是pregame中没有了#include也灭有类似的格式。

这就是预编译的作用他把game.c中包含的头文件加在main函数的上面.

gcc -o game game.c 生成 可执行程序 game

gcc -o pregame pregame.c 生成可执行程序pregame

注意:这两个命令,我们忽略了as和ld的步骤。

pregame最好用.c做为文件名

发现 game和pregame的运行结果一样,这也说明了预编译的作用.

总结一下预编译的作用:(这些是lorne大人总结的,与我无关)

1. 把"include"的文件拷贝到要编译的源文件中。

2. 用实际值替代"define"的文本。

3. 在调用宏的地方进行宏替换。

2.编译。

这个过程是用于生成汇编语言。这是编译过程的一步,是一步,是一步啊,同志们~~~~~~~~~~~~~~!!

gcc -S -o aspregame pregame.c

会生成一个aspregame文件,看看是什么东西?

file aspregame

aspregame: ASCII assembler program text

嘿嘿出现了,汇编程序文本.

有兴趣你可以看一下

cat aspregame

.file "pregame.c"

.section .rodata

.LC0:

.string "Hello World!"

.text

.globl main

.type main, @function

main:

leal 4(%esp), %ecx

andl $-16, %esp

pushl -4(%ecx)

pushl %ebp

movl %esp, %ebp

pushl %ecx

subl $4, %esp

movl $.LC0, (%esp)

call puts

addl $4, %esp

popl %ecx

popl %ebp

leal -4(%ecx), %esp

ret

.size main, .-main

.ident "GCC: (GNU) 4.1.0 20060304 (Red Hat 4.1.0-3)"

.section .note.GNU-stack,"",@progbits

传说中的汇编。

最好用.asm作为文件名。

3.生成目标文件.

这一步我们可以用gcc来完成,但是还是用as吧,总觉得一步到位的东西,不是很适合学习。

as -o ldaspregame aspregame

会生成ldaspregame文件

看看他是什么?

file ldaspregame

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

ELF格式的文件,浮动的,意思是这个程序的地址是可以被修改来适应初始地址,其实就是未连接的目标文件。

注意:我们可以把任何的一个.c文件通过gcc -S变成汇编,在把他变成目标文件。

最要用.o做为文件名

4.连接成为可执行文件

那么现在我们来生成可执行文件吧

这里要说明什么是动态链接库,相当于winxxx中的dll文件,在这里是so文件,ELF格式就是支持动态链接库的。

gcc -o exldaspregame ldaspregame

好了声称了可执行文件ldaspregame

任何一个.c文件都可以生成目标文件,他们需要被连接来执行。

这里我有一个问题,希望高手可以解答:

本来我想用ld来连接文件,ld ldaspregame

但是提示错误为:

ld: warning: cannot find entry symbol _start; defaulting to 08048094

对‘puts’未定义的引用

以为是没有设置要连接的库文件。

ld /bin/libc.so.6 ldaspregame

仍然错误

提示错误为

ld: warning: cannot find entry symbol _start; defaulting to 08048094

entry symbol_start究竟是什么东西?gcc又是怎样完成这一步骤的?

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多