您的位置:首页 > 编程语言 > C语言/C++

程序的实现过程(编译、链接、执行)

2017-03-14 17:48 211 查看
在ANSI C的任何一种实现中,存在两个不同的环境

第1种是翻译环境,在这个环境中源代码被转换为可执行的机器指令。
第2种是执行环境,它用于实际执行代码。

标准明确说明:这两种环境不必位于同一台机器上。

例如,交叉编译器就是在同一台机器上运行,但它所产生的可执行代码运行于不同类型的机器上。操作系统也是这样。

翻译阶段,程序实现过程如下图:



翻译阶段的两个步骤:

组成一个程序的每个源文件(source code)通过编译过程分别转换成目标代码(object code)
每个目标文件由
链接器(linker)捆绑在一起,形成一个单一而完整的可执行程序(executable)

注:链接器同时也会引入标准C函数库中任何被该程序所用到的函数,并且它可以搜索程序员个人的程序库,将其需要的函数也链接到程序中。

而编译本身也分为三个阶段组成:

预处理器(preprocessor)处理--预编译。 在这个阶段,预处理器在源代码上执行一些文本操作。
源代码经过解析,判断它的语句的意思。这个阶段产生绝大多数的错误和警告。
形成符号表,产生目标代码
下面截图表示程序在翻译阶段的具体功能:



注:
①文件后缀名*.i、*.s、*.o在类unix系统中,可通过gcc相关命令生成对应文件。

②符号表:在计算机科学中,符号表是一种用于语言翻译器(例如编译器和解释器)中的数据结构。在符号表中,程序源代码中的每个标识符都和它的声明或使用信息绑定在一起,比如其数据类型、作用域以及内存地址。符号表在编译程序工作的过程中需要不断收集、记录和使用源程序中一些语法符号的类型和特征等相关信息。这些信息一般以表格形式存储于系统中。如常数表、变量名表、数组名表、过程名表、标号表等等,统称为符号表。

程序执行的过程:

程序必须载入内存中(由冯曼依诺计算机体系决定)。在有操作系统的环境中:一般这个由操作系统完成。在独立的环境中,程序的载入必须由手工安排,也可能是通过可执行代码置入只读内存来完成。
 程序的执行便开始。接着便调用main函数
开始执行程序代码。这个时候程序将使用一个运行时堆栈(stack),存储函数的局部变量和返回地址。程序同时也可以使用静态(static)内存,存储于静态内存中的变量在程序的整个执行过程一直保留他们的值。
终止程序。正常终止main函数;也有可能是意外终止。

运行时和编译时的本质:

像标志符(类型名、变量名、函数名等)、类型定义、const关键字、访问限定符(public/private/protected)、引用(&)等只是存在于源码中,他们不会被带入二进制可执行程序中,这是“编译时”的本质。
存在于二进制可执行程序中的只是指令、地址和数据,没有别的东西(实际上地址也是数据的一种),这就是“运行时”的本质。
C/C++源代码中的语句、指针和变量都将被转化成二进制程序中的指令、地址和数据。因此,通过名字直接引用一个变量、对象即其成员,这样的代码在编译和链接完成后,实际上都被转换成了通过变量、对象或成员变量的地址(即内存元的地址)进行访问。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息