程序的编译与执行环境

前言

  • 本文简要概述程序的编译环境与执行环境的流程,其中编译环境中的预处理过程,重点放在了另外一边博客:预处理

  • 博主的问题收集与自我解答:New Young

  • 转载请标明出处:New Young

程序的环境

在ANSI C 的任何一种实现中:都有2种环境:

编译环境: 编译器将源代码(后缀.c文件中的代码)转换为包含机器语言(二进制代码)的目标代码文件,同时通过链接器 将 目标文件与 库文件,启动代码文件进行链接 生成 可执行的代码文件。这一过程又可细分为 预处理,编译,汇编,链接。

执行环境:执行可执行代码文件 。

image-20220124202843486

编译环境

预处理

预处理进行的是文本操作,不进行任何相关计算。

  • 库文件的包含

  • (.h)文件中是一些声明或者是自定义类型的声明等。一旦程序调用某些未声明函数,程序会creash。

  • 宏的文本替换和预处理指令的操作等

  • 去除程序注释内容

  • 。。。

编译

分为2步:

  • 分别将每个文件中的全局变量名和函数名进行汇总。

  • 这也是,为什么在使用函数或者变量时,要进行 提前声明,或者定义式声明,或者引用式声明(extern)

  • image-20220125143111145

  • 通过 词法分析,语法分析,语义分析,分析代码的意思,将源代码转换为汇编语言。

image-20220125111436348

汇编

  • 将编译完成的汇编代码 转换为 机器可以识别的二进制代码,生成目标代码文件.

  • 对每个符号和其地址 汇总到一个表中—符号表。

  • 这样在程序遇到符号名,就可以通过地址,访问符号。

image-20220125143514900

链接

  • 对所有符号表进行合并和重定位。

因为不同的文件中的符号可能有重名的,这样就需要确定唯一的有效符号。

image-20220125143707259

  • 合并断表。

  • 将启动代码,库代码(更多的是将程序用到库函数代码进行链接),目标代码文件,链接,生成可执行文件 (,exe)。

  • 这也是为什么,在使用库函数 printf等,我们只需要在文件中 include <stdio.h>等库文件。

执行环境

  • 程序必须载入内存中。在有操作系统的环境中:一般这个由操作系统完成。在独立的环境中,程序的载入必须由手工安排,也可能是通过可执行代码置入只读内存来完成。

  • 程序的执行便开始。接着便调用main函数。

  • 开始执行程序代码。这个时候程序将使用一个运行时堆栈(stack),存储函数的局部变量和返回地址。程序同时也可以使用静态(static)内存,存储于静态内存中的变量在程序的整个执行过程一直保留他们的值。

  • 终止程序。正常终止main函数;也有可能是意外终止 .

猜你喜欢

转载自blog.csdn.net/qq_55439426/article/details/122690678