从源文件到可执行文件

        Hello,看这篇文章的每一个人,相信你们肯定对编写代码并不陌生,例如下面一个简单的C语言代码。

#include <stdio.h>
int main(void)

{
    printf("Hello World!\n");
    return 0;
}

         大家对这个程序熟悉得不能再熟悉了(这不是输出Hello World!嘛),对的,没错。这是我们走入编程世界的第一个程序,但是很人对这个Hello.c文件是如何到可以执行的EXE文件,却是很模糊,甚至是不知道,下面我将为大家讲解我们平时写的程序变成可执行的EXE文件是一个怎样的过程。

       在此之前先看看咱们下面的这些问题,考验大家是否知道答案。如果不知道也没关系,我也会给出答案和解析。

热身提问:

1、CPU可以解析和运行的程序形式称为什么代码?

2、将多个目标文件结合生成EXE文件的工具称为什么?

3、扩展名为.obj的目标文件的内容,是源代码还是机器语言代码?

答案与解析:

1、机器语言代码。

通过编译源代码得到的是机器语言代码。

2、链接器

通过编译和链接。得到EXE文件。

3、机器语言代码

通过对源文件进行编译,得到目标文件。例如,C语言中,将Hello.c这个源文件编译后,就会得到Hello.obj这个目标文件。目标文件的内容就是机器语言代码。

:上面的机器语言代码,可能大家有点陌生,但其实机器语言代码就是二进制文件,能被CPU直接理解。

1、计算机只能运行机器代码

        上面的Hello.c运行后,在窗口会显示 Hello World!这一条信息,类似Hello.c这样,用某种编程语言编写的程序就称为源代码,保存源代码的文件称为源文件

        注:因为源文件是简单的文本文件,故用计算机自带的记事本等文本编辑器就可以编写。

       但Hello.c的源代码是无法运行的,因为CPU能直接解析并运行的不是源代码而是机器语言代码(二进制)的程序。用任何编程语言编写的源代码,最后都要翻译成机器语言代码,否则CPU就不能理解,这个程序也运行不了。

2、编译器负责转换源代码

       能够把C语言等高级编程语言编写的源代码转换成机器语言代码的程序称为编译器。每个编写源代码的编程语言都需要其专用的编译器。将C语言编写的源代码转换成机器语言代码的编译器称为C编译器。

       编译器首先读入代码的内容,然后再把源代码转换成机器语言代码。其中读入的源代码还要经过语法解析、句法解析、语义解析等,才能生成机器语言代码。

       注:根据CPU类型的不同,机器语言代码的类型也不同。因而,编译器不仅和编程语言的种类有关,和CPU的类型也是相关的。

3、仅靠编译时无法得到可执行文件的

      编译器编译源代码后,就会生成机器语言代码文件。但是这个文件是无法直接运行的。因为编译之后还需要进行“链接”处理,才能得到可以运行的EXE文件。

       编译后生成的不是EXE文件,而是拓展名为“.obj”的目标文件。Hello.c编译后,就生成了Hello.obj目标文件。虽然目标文件的内容是机器语言代码,但却无法直接运行。Why?原因就是当前程序还处于未完成状态。

       我们知道一个函数是由函数原型和函数定义组成,但是上面的Hello.c文件中的printf()函数却没有这些,故必须将存储着printf()函数的信息的目标文件同Hello.obj结合,否则处理就不完整,EXE文件也就无法完成。

       把多个目标文件结合,生成一个EXE文件的处理就是链接,运行链接的程序就称为链接器( linkage editor)。链接器的作用是,把编写的目标代码、系统的标准启动代码和库代码这3部分合并成一个文件,即可执行文件。

4、启动及库文件

        目标代码文件缺失启动代码(startup code)。启动代码充当着程序和操作系统之间的接口。因此,即使程序不调用其他目标文件的函数,也必须要进行链接,并与启动结合起来。

       库文件指的是把多个目标文件集成保存到一个文件中的形式。其中库文件又分静态链接库(拓展名为.lib的文件)和动态链接库(拓展名为.dll的文件)。静态链接库中的库文件会直接和EXE文件结合,而动态链接库中的库文件在程序运行的时候动态结合,也就是说EXE文件在没运行之前,这个EXE文件已经有了静态链接库中我们程序需要的库文件信息,但需要的DLL文件信息是没有的,需要程序运行的时候,DLL文件才会与EXE文件结合。

       链接器指定库文件后,就会把从中把需要的目标文件抽取出来,并同其他目标文件结合生成EXE文件。

注:头文件(例如上面Hello.c中的stdio.h文件)存储着函数的函数名、参数、函数类型等信息,但函数具体实现的代码是在库文件里。可以这么理解函数声明在头文件,而函数定义在库文件中。stdio.h不是库文件,而是头文件。


         这只是一篇比较简短且简略的介绍源文件到可执行文件的文章,其实源文件到可执行文件的过程,还有一些详细的内容,这些需要你们自己去查找深入,上面的内容仅是一个大体的,下面我再用流程图为大家总结如下:

​​​​​​​

 

                                                以上便是这篇文章的内容,感谢大家阅读。

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 源文件可执行文件经历以下步骤: 1. 预处理:对源代码进行宏替换、头文件展开等操作,生成一个被称为预处理文件的中间文件。 2. 编译:将预处理文件转换为汇编代码,即将高级语言的代码转换为汇编语言的代码。 3. 汇编:将汇编代码转换为机器码,生成一个目标文件。 4. 链接:将目标文件与库文件进行链接,生成可执行文件。链接的过程包括符号解析、重定位等步骤,确保所有的符号引用都能正确地链接到符号定义。 使用现代编译器时,以上步骤通常会自动完成。 ### 回答2: 源文件可执行文件经历以下几个步骤: 1. 预处理(Preprocessing):在这个阶段,预处理器将对源文件进行预处理,处理包括注释的删除、宏的展开等。预处理的结果是一个经过处理的源文件,通常以.i或者.ii作为文件扩展名。 2. 编译(Compilation):编译器将预处理后的源文件转换成汇编语言代码(Assembly code),此时生成的文件通常以.s作为文件扩展名。汇编语言是一种低级的语言,它与机器指令一一对应。 3. 汇编(Assembly):在汇编阶段,汇编器将汇编语言代码转换成机器代码(Machine code),即二进制指令。生成的文件通常以.o作为文件扩展名。 4. 链接(Linking):链接器将编译和汇编得到的目标文件与其他的目标文件或者库文件进行链接,生成最终的可执行文件。链接器的主要作用包括解析全局变量和函数的引用、解析函数调用的地址、将目标文件和库文件中的定义合并等。生成的可执行文件文件扩展名根据操作系统的不同可能有所变化,常见的有.exe(Windows)和.out(Linux)等。 总之,源文件可执行文件的转换过程包括预处理、编译、汇编和链接四个主要步骤。每个步骤都有自己独特的功能,并且需要不同的工具和处理。通过这个过程,我们可以将高级语言编写的源代码转换成计算机可以直接执行的机器代码。 ### 回答3: 源文件可执行文件经历以下几个步骤: 1. 预处理:在这个步骤中,源文件会经过预处理器将其中的预处理指令(如#include、#define等)进行替换或扩展。预处理器还可以进行条件编译和宏展开等操作,最终生成一个被修改过的源文件。 2. 编译:编译阶段是将预处理后的源文件转换为汇编语言的过程。编译器将源文件中的每个函数和变量编译成对应的汇编代码,并生成一个汇编语言文件。 3. 汇编:在这个步骤中,汇编器将汇编代码转换为机器语言指令。汇编器会将汇编语言文件中的每一条指令翻译为机器指令,并生成一个目标文件。 4. 链接:链接阶段将目标文件与其他必要的库文件进行合并,生成可执行文件。链接器会将目标文件中的函数和变量与库文件中的函数和变量进行匹配,并生成最终的可执行文件。 最终的可执行文件就是经过上述步骤处理完成的程序。当我们运行这个可执行文件时,计算机会按照其中的机器指令来执行程序,实现相应的功能。整个过程可以通过命令行编译器(如gcc)或集成开发环境(IDE)中的编译器工具链来完成。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值