C++从代码到可执行程序 您所在的位置:网站首页 用c语言编写的源代码程序怎样才能执行 C++从代码到可执行程序

C++从代码到可执行程序

2023-12-05 16:42| 来源: 网络整理| 查看: 265

1. 从代码到可执行程序的执行

无论是windows操作系统还是linux操作系统,C++编写代码到可执行程序的执行,都经过了预处理、编译、汇编、链接、运行5个步骤。有时候我们也将预编译、编译和汇编统称为编译。下面分别介绍这5个步骤

预处理

预处理过程进行的操作:

1. 将所有的“#define”删除,并且展开所有的宏定义 2. 处理所有的条件编译指令,比如“#if”、“#ifdef”、“#elif”、“#else”、“#endif” 3. 处理“#include”预编译指令,将被包含的头文件插入到该编译指令的位置。(这个过程是递归进行的,因为被包含的文件可能还包含了其他文件) 4. 删除所有的注释“//”和“/* */”。 5. 添加行号和文件名标识,方便后边编译时编译器产生调试用的行号信息以及编译时产生编译错误或警告时能够显示行号。 6. 保留所有的#pragma编译指令,因为编译器需要使用它们。

编译

编译过程就是把预处理完的文件进行一系列的词法分析、语法分析、语义分析以及优化后产生相应的汇编代码文件,这个过程是整个程序构建的核心部分,也是最复杂的部分之一。为了使计算机能执行高级语言源程序,必须先用一种称为“编译器(complier)”的软件(也称编译程序或编译系统)。编译是以源程序文件为单位单别编译的,头文件不参加编译。(在VC6.0里如果编译头文件则会弹出没有可以工具函数,在VS2013中,对于头文件,编译按钮为灰色,不可用状态。)

现在编译器种类很多,不同编译器区别在于对编译过程做了优化,添加了一些库函数或类库。优化处理是编译系统中一项比较艰深的技术。它涉及到的问题不仅同编译技术本身有关,而且同机器的硬件环境也有很大的关系。优化一部分是对中间代码的优化。这种优化不依赖于具体的计算机。另一种优化则主要针对目标代码的生成而进行的。对于前一种优化,主要的工作是删除公共表达式、循环优化(代码外提、强度削弱、变换循环控制条件、已知量的合并等)、复写传播,以及无用赋值的删除,等等。后一种类型的优化同机器的硬件结构密切相关,最主要的是考虑是如何充分利用机器的各个硬件寄存器存放的有关变量的值,以减少对于内存的访问次数。另外,如何根据机器硬件执行指令的特点(如流水线、RISC、CISC、VLIW等)而对指令进行一些调整使目标代码比较短,执行的效率比较高,也是一个重要的研究课题。

编译技巧:编译的作用是对源程序进行词法检查、语法检查和中间代码生成。编译时对文件中的全部内容进行检查,如果有语法错误,编译结束后会显示出所有的编译出错信息,开发人员可以根据错误提示修改程序。对于新写的一个保护多个文件的工程,一开始采用源文件分别编译,这样容易发现每个源文件的自身错误,限定了错误的范围,如果一开始就采用全部编译,多个源文件可能会产生许多错误,无形中增加了开发难度。如果每个源文件都通过了编译,再将所有文件进行编译。对源文件分别编译对于调试,纠错是一种很好的方法。

汇编

汇编实际上指把汇编语言代码翻译成目标机器指令的过程。汇编器的编译过程相对于编译器来讲比较简单,它没有复杂的语法,也没有语义,也不需要做指令优化,只是根据汇编指令和机器指令的对照表一一翻译。对于被翻译系统处理的每一个语言源程序,都将最终经过这一处理而得到相应的目标文件。目标程序一般以.obj或.o作为后缀,这具体看操作系统,如Windows是下是.obj目标文件,Linux下是.o目标文件。目标文件中所存放的也就是与源程序等效的目标机器语言代码

链接

前面提到过,编译是对源文件分别进行的,每个源文件都产生一个目标文件。但由汇编程序生成的目标文件并不能立即就被执行,因为各个源文件之间可能是有相互联系的,例如,某个源文件中的函数可能引用了另一个源文件中定义的某个符号(如变量或者函数调用等);在程序中可能调用了某个库文件中的函数,等等。所有的这些问题都需要经链接解决,即将源程序产生的多个目标文件链接为一个整体。即通过系统提供的“连接程序(linker)”将一个程序的所有目标程序和系统的库文件以及系统提供的其他信息连接起来,最终形成一个可执行的二进制文件,它的后缀是.exe,此时产生了完整的执行文件。

链接程序的主要工作就是将有关的目标文件彼此相连接,如源文件产生的目标文件和库文件等,使得所有的这些目标文件成为一个能够被操作系统装入执行的统一整体。根据指定的库函数的不同,链接处理可分为两种:

(1)静态链接:在这种链接方式下,函数的代码将从其所在地静态链接库中被拷贝到最终的可执行程序中。这样该程序在被执行时这些代码将被装入到该进程的虚拟地址空间中。静态链接库实际上是一个目标文件的集合,其中的每个文件含有库中的一个或者一组相关函数的代码。

(2)动态链接:此种方式下,函数的代码被放到称作是动态链接库或共享对象的某个目标文件中。链接程序此时所作的只是在最终的可执行程序中记录下共享对象的名字以及其它少量的登记信息。在此可执行文件被执行时,动态链接库的全部内容将被映射到运行时相应进程的虚地址空间。动态链接程序将根据可执行程序中记录的信息找到相应的函数代码。

对于可执行文件中的函数调用,可分别采用动态链接或静态链接的方法。使用动态链接能够使最终的可执行文件比较短小,并且当共享对象被多个进程使用时能节约一些内存,因为在内存中只需要保存一份此共享对象的代码。但并不是使用动态链接就一定比使用静态链接要优越。 

链接将相关关联文件链接起来,所以这个阶段的错误不好调试,发生错误可能在我们自己编写的代码中,也有可能是与别的文件关联产生的,对于因关联产生错误就比较复杂了,有时需要调整编译器或链接器。

运行

运行阶段就比较简单了,直接执行前面链接过程产生的可执行的二进制文件即可得到运行结果

 

 

2.Windows下代码到可执行程序的过程

1 .cpp经过预处理生成.i文件经过编译生成.asm文件经过汇编生成.obj文件(COFF格式的二进制目标文件) 经过链接(和其他obj文件及静态链接库文件)生成PE格式的可执行文件

2. 编译阶段,包括预处理、编译、汇编,由cl.exe完成。

3. 链接阶段由,link.exe完成。

 

3. Linux下代码到可执行程序的过程

 

 

 

 



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有