01程序编译过程分析,预处理,编译,汇编,链接

目录

前言

一:hello word由浅入深

二:预处理

三:编译

四:汇编

五:链接

总结:


前言


我们大多数开发人员在编写完程序之后都会通过相应的IDE执行编译的操作,将所编写的源代码转换成计算机可以识别并执行的文件。这个从源代码转换成可执行文件的过程有相应的IDE帮助我们完成,很多朋友对于这个过程都不太熟悉,今天我们就一起探讨下可执行文件的生成过程,这个过程又叫做程序的编译与链接。

一:hello word由浅入深


对于程序员开发者来说,hello world程序的编写,大家闭上眼睛都能写出来,今天我们就以hello world为例来探讨一下可执行文件的生成过程,废话不多说,下面就是hello word的源码

#include <stdio.h>
int main()
{
    printf("hello, world\n");
}

上面代码的功能就是输出hello,word。然而计算机不可能直接执行hello world.c下面我们用一张图来讲一下hello world.c是如何被被执行。


从上面的图中,我们大致可以看到,hello.c要想变成计算机可以执行的hello(可执行目标文件)需要经过预处理,编译,汇编,链接等步骤,这些步骤主要是干什么的,有各自有什么作用,我们下面一一进行分析。

二:预处理



首先我们先来看一下预处理的执行命令

– $gcc –E hello.c –o hello.i
– $cpp hello.c > hello.i

预处理执行的功能:

  • 删除“#define”并展开所定义的宏
  • 处理所有条件预编译指令,如“#if”,“#ifdef”, “#endif”等
  • 插入头文件到“#include”处,可以递归方式进行处理
  • 删除所有的注释“//”和“/* */”
  • 添加行号和文件名标识,以便编译时编译器产生调试用的行号信息
  • 保留所有#pragma编译指令(编译器需要用)

经过预编译处理后,得到的是预处理文件(如,hello.i) ,它还是一个可读的文本文件 ,但不包含任何宏定义
上面所说的第3条插入头文件到“include”处,可以理解为将头文件里面的内容进行展开,下面用一张图来进行描述 

 

 

三:编译



编译过程就是将预处理后得到的预处理文件(如 hello.i)进行词法分析、语法分析、语义分析、优化后,生成汇编代码文件。用来进行编译处理的程序称为编译程序(编译器,Compiler)
编译命令

– $gcc –S hello.i –o hello.s
– $gcc –S hello.c –o hello.s
– $/user/lib/gcc/i486-linux-gnu/4.1/cc1 hello.c

上面3条编译指令表明,我们可以通过.i文件输出汇编文件.s同时也可以直接将.c文件编译成.s文件。第3条指令则是通过编译器直接执行,与前两条执行效果一样。gcc命令实际上是具体程序(如ccp、cc1、as等)的包装命令,用户通过gcc命令来使用具体的预处理程序ccp、编译程序cc1和汇编程序as等
经过编译后,得到的汇编代码文件(如 hello.s)还是可读的文本文件,CPU无法理解和执行它,不要着急,我们接下来看下一步汇编命令的执行过程

四:汇编



首先我们先了解下汇编代码文件(由汇编指令构成)称为汇编语言源程序,其实就是上面编译过程结束之后生成的.s文件,这个文件就是汇编代码文件,改文件是有一条条汇编指令构成,汇编的作用就是讲这一条条汇编指令转换成对应的机器执行。
• 汇编程序(汇编器)用来将汇编语言源程序转换为机器指令序列(机器语言程序) 
• 汇编指令和机器指令一一对应,前者是后者的符号表示,它们都属于机器级指令,所构成的程序称为机器级代码,汇编的过程比较简单,只需要将相应的汇编指令翻译成对应的机器指令即可,没有什么复杂的变化。

汇编命令

– $gcc –c hello.s –o hello.o
– $gcc –c hello.c –o hello.o
– $as hello.s -o hello.o (as是一个汇编程序)

汇编结果是一个可重定位目标文件(如,hello.o),其中包含的是不可读的二进制代码,必须用相应的工具软件来查看其内容

五:链接


哇,经过了上面一系列的流程,终于到了最后一步,我们的hello world 终于要完成了,下面我们就来看下最后一步链接的处理吧。
预处理、编译和汇编三个阶段针对一个模块(一个*.c文件)进行处理,得到对应的一个可重定位目标文件(一个*.o文件),但是在程序的编写过程中,我们都是多个.c文件的,这样经过上面的预处理,编译汇编的过程之后我们得到的也是多个.o(可重定位目标文件),但是我们在最终执行的时候是只有一个可执行文件的,这个过程就是连接的目的了。
链接过程将多个可重定位目标文件合并以生成可执行目标文件,大家可以看下最初时候的图,在最后一步连接的过程中,我们不只是要hell.o而且还需要printf.o(代码中含有printf函数),链接就是将这连个.o合并为一个生成可执行目标文件
链接命令

– $gcc –static –o myproc main.o test.o
– $ld –static –o myproc main.o test.o

–static 表示静态链接,如果不指定-o选项,则可执行文件名为“a.out”

总结:



经过了上面的介绍,我们应该对程序的编译和链接有了相应的了解,在回头看看最开始的图片是不是更加清晰明了。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值