C的编译过程

简介:

这个编译过程人人皆知,但是真正理解的却不多,好好收藏这篇好文章!!


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

2.  编译生成汇编,

3.   汇编生成目标文件,

4.  目标文件连接库文件生成可执行文件,

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


这里的例子选自 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文件都可以生成目标文件,他们需要被连接来执行







相关文章
|
6月前
|
机器学习/深度学习 运维 自然语言处理
系统程序的编译与处理
系统程序的编译与处理
|
程序员 Linux Android开发
libYuv编译
安卓使用NDK编译libYuv库
297 0
|
10月前
|
缓存 Java Shell
ThingsBoard详细编译指南2.4.3
ThingsBoard详细编译指南2.4.3
331 0
|
10月前
|
C++
C++程序的编译过程
C++程序的编译过程
|
自然语言处理 编译器 C语言
C/C++程序的编译过程
C/C++程序的编译过程
180 0
C/C++程序的编译过程
jpegNPP编译为so
jpegNPP编译为so
59 0
|
Web App开发 存储 缓存
V8 编译浅谈
本文是一个 V8 编译原理知识的介绍文章,旨在让大家感性的了解 JavaScript 在 V8 中的解析过程。
V8 编译浅谈
|
开发工具 C++ git
DCMTK-001-3.6.6编译
DCMTK-001-3.6.6编译
240 0
DCMTK-001-3.6.6编译
|
Python
编译过程
编译系统的运行过程 源代码 --> 机器代码 解释器运行程序的方法 1.直接运行高级编程语言 2.转换高级编程语言码到一些有效率的字节码(Bytecode),并运行这些字节码 Python解释语言特点 "拆解"代码: 首先当用户键入代码交给Python处理的时候会先进行此法分析,例如用户...
772 0
|
编译器 开发工具 IDE
编译问题汇总
每次在编译各类第三方库的时候都会碰到很多问题,基本上都是通过Google解决,其实简单反思一下就会发现是对于系统了解的不够,对于各类标准也是了解甚少。所以一而再再而三发生的问题其实是可以尽量去避免的。
1925 0

热门文章

最新文章