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

时间: 2024-12-03 22:12:07

C的编译过程的相关文章

详解 Weex JS Framework 的编译过程

之前写了一篇文章<Weex 框架中 JS Framework 的结构>概述了 JS Framework 的整体结构,其中编译过程写的有些简略,这里再详细介绍一下. 一句话概括 JS Framework 的编译过程就是: 将 JS Bundle 转换成 Virtual DOM 发送到原生模块渲染. 这个过程涉及三种数据类型:JS Bundle .Virtual DOM .Vm . JS Bundle 是由 .we 文件转换过来的,会被视为代码而执行. Virtual DOM 是描述页面结构的 J

给jikes指定encoding属性的编译过程

编译|过程 jikes是一个比javac速度快的java编译器,它是IBM的一个开放源码项目 在一些Application Server运行时,我们为了提高运行的速度,会选择对jsp文件进行预编译,但是如果项目比较大的话,对于所有的jsp编译会花费很长的时间,所以这个时候需要选择一个快速的java编译器,据说Symantec的sj速度最快,但是目前好像没有继续开发,不支持jdk1.4以上了,所以我们选择稍次之的jides编译器,不过jikes没有提供对win32平台的encoding属性的支持,

WinCE系统的编译过程图解

在WinCE系统中,当我们完成了相关的开发和系统定制工作以后,会编译WinCE系统,最后生成NK.bin和NK.nb0.我现在用WinCE6.0在自己的PC上面编译一次用时19分16秒(有一天无聊,就测了一下).下面介绍一下WinCE系统的编译过程,大致分为4个阶段:编译阶段(Compile phase),系统产生阶段(Sysgen phase),文件拷贝阶段(Release copy phase)和生成映像阶段(Make Run-time image phase). 过程如图: 从图中可以看出

PHP编译过程中常见错误信息的解决方法

PHP编译过程中常见错误信息的解决方法 在CentOS编译PHP5的时候有时会遇到以下的一些错误信息,基本上都可以通过yum安装相应的库来解决.以下是具体的一些解决办法: checking for BZip2 support- yes checking for BZip2 in default path- not found configure: error: Please reinstall the BZip2 distribution Fix: yum install bzip2-devel

iOS编译过程的原理和应用

前言 一般可以将编程语言分为两种,编译语言和直译式语言. 像C++,Objective C都是编译语言.编译语言在执行的时候,必须先通过编译器生成机器码,机器码可以直接在CPU上执行,所以执行效率较高. 像JavaScript,Python都是直译式语言.直译式语言不需要经过编译的过程,而是在执行的时候通过一个中间的解释器将代码解释为CPU可以执行的代码.所以,较编译语言来说,直译式语言效率低一些,但是编写的更灵活,也就是为啥JS大法好. iOS开发目前的常用语言是:Objective和Swif

《深入理解Android:Telephony原理剖析与最佳实践》一2.2 Android源代码下载及编译过程

2.2 Android源代码下载及编译过程 前面完成了Ubuntu.JDK.Android SDK的安装和配置,接着开始下载和编译Android 4.0源代码,这个过程简单但花费的时间比较长,请读者先有个心理准备. Android 4.0的代号为Ice Cream Sandwich,简称ICS,中文名称冰淇淋三明治. 2.2.1 工作目录设置 本书采用ICS名称的文件夹作为Android 4.0源代码的根目录,在用户根目录下新建代码根目录ICS文件夹,并设置此目录为工作目录,在.bashrc中增

C语言的编译过程

C语言的编译链接过程要把编写的c程序(源代码)转换成可以在硬件上运行的程序(可执行代码),需要进行编译和链接. 编译就是把文本形式源代码翻译为机器语言形式的目标文件的过程. 链接是把目标文件.操作系统的启动代码和用到的库文件进行组织形成最终生成可执行代码的过程. 过程图解如下: 从图上可以看到,整个代码的编译过程分为编译和链接两个过程,编译对应图中的大括号括起的部分,其余则为链接过程. 编译过程 编译过程又可以分成两个阶段:编译和会汇编. 编译        编译是读取源程序(字符流),对之进行

android4 3-Android4.3源码编译过程中出错

问题描述 Android4.3源码编译过程中出错 虚拟机Ubuntu12.04 64bit 编译Android4.3过程中出现以下问题: make: *** 没有规则可以创建"out/host/linux-x86/obj/SHARED_LIBRARIES/libdvm_intermediates/mterp/out/InterpAsm-x86.o"需要的目标"dalvik/vm/mterp/out/InterpAsm-x86.S". 停止. 源码在ubuntu12.

LFS编译过程必备辅助手册(一)

LFS编译过程必备辅助手册(一) 很多人对Linux进行了一定的学习之后,都会有一种自己从头搭建一套Linux的想法,在这方面LFS和Gentoo都是不错的起点.不过虽然它们已经尽量提供详细文档了,但对于初学者来说还是存在一定的困难的. 因此本站特邀 PHILO (@看见微软我就跑)和 米油 两位同学将他们自己学习LFS的经验分享给大家,也希望大家一起来参与到LFS之旅中. 前言 LFS(Linux from scratch)是从源代码开始编译Linux操作系统.如果需要深度定制Linux操作系