E:现在我们看一下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又是怎样完成这一步骤的?
如果您喜欢这篇文章请点击右上角按钮, 即可分享到《朋友圈》或许 你小小的一个分享动作就可以照亮无数人的命运。 欢迎关注公众微信:yingchunhua365 扫描以下二维码
传递正能量,分享励志故事, 从这里起航…… 请把正能量传递下去, 帮助和影响更多的人, |
C程序编译过程
最新推荐文章于 2023-06-30 19:16:23 发布