程序的运行过程(详解)

本文详细介绍了C/C++程序的翻译和执行环境,包括预编译的头文件包含和#define替换,编译成汇编代码,汇编成目标文件以及链接过程中的符号表合并和重定位。此外,还提到了使用VScode进行环境配置的相关步骤。
摘要由CSDN通过智能技术生成

为更清晰的理解本博客中的内容,建议下载VScode及配置相关环境来实践(当然仅阅读也能理解)下载教程链接: VScode安装、C/C++环境配置


一、程序的翻译环境和执行环境

在ANSIC的任何一种实现中,存在两个不同的环境。

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

image.png

翻译环境

组成一个程序的每个源文件通过编译过程分别转换成目标代码(object code)。
每个目标文件由链接器(linker)捆绑在一起,形成一个单一而完整的可执行程序。
链接器同时也会引入标准C函数库中任何被该程序所用到的函数,而且它可以搜索程序员个人 的程序库,将其需要的函数也链接到程序中

每一个源文件都会经过编译器的单独处理生成一个目标文件。
image.png

编译本身的几个阶段

image.png

二、程序编译过程详解(接上文)

1.预编译过程

预编译中的头文件的包含

写完test.c后(test.c是自己所编写的C语言程序)按ctrl和·(注意是撇,在esc键下面的那一个(若不管用再同时按shift键))输入指令gcc test.c -E 结果为:
image.png
若想将仔细观察输出的内容,可以将其输入到test.i(test.i文件是系统自创的)文件中,具体做法如下:
输入指令gcc test.c -E -o test.i 将上面的代码输入到test.i文件中(注意是.i文件,不要是.其它)。
image.png
test.c与test.i文件的对比:
image.png
那么这是什么呢?
我们知道编写C程序时需添加头文件如#include<stdio.h>,而在代码运行时会将该头文件包含进test.c文件中,输入指令gcc test.c -E -o test.i此时生成的test.i文件中所包含的就是简化后的stdio.h和编写的C程序,该过程就是预编译中的头文件的包含。

注释的删除和#define定义的替换

将上述代码进行修改,重新生成test.i文件(若test.i文件仍是未修改前的,需先将test.c文件进行保存再重新生成)。
结果如下:
image.png
可以看出编译器删除了注释,并将#define定义进行替换。这就是注释的删除和#define定义的替换

2.编译过程

翻译成汇编代码

输入gcc test.i -S生成test.s文件,打开test.s可以看到:
image.png
此时生成的test.s文件中的就是由源代码翻译成的汇编代码。(相信大家对什么是汇编代码有一定的了解,就不做过多解释了)该过程包括语法分析、词法分析、语义分析、符号汇总。(其中符号汇总会在文末与其它一起讲解)

3.汇编过程

转化成目标文件

接上文,输入指令gcc test.s -c生成一个test.o文件,结果如下:
image.png
可以看出,该文件是二进制文件也是目标文件(在VS上目标文件后缀是.obj 而gcc上是.o)。汇编过程是将汇编代码转化成目标文件同时生成符号表(符号表文末与其它一同讲解),方便链接器的运行。

4.链接过程

链接过程中会进行合并段表和符号表的合并和重定位。(在链接器中进行的)
上文提到过每一个源文件都会经过编译器的单独处理生成一个目标文件,而链接过程则与其密切相关。
对上述代码稍微进行改造并添加了一个add.c文件。(链接过程会与符号汇总和符号表一同讲解)
改造后代码如下:
image.png

符号汇总与形成符号表

在符号汇总过程中会对代码进行分析,查找代码是否存在全局的符号(如Add、main)将其汇总起来,接着在汇编过程中形成符号表。(发生在编译过程)
image.png

合并段表

接下来进行合并段表与符号表的合并和重定位。(发生在链接过程)
在这里需要提一下,此时已经生成.o文件即目标文件,该目标文件是有格式的。以gcc为例,目标文件的格式是elf格式。接下来简要概括合并段表的过程。
image.png

符号表的合并和重定位

将上述符号表进行合并,按地址是否有效决定合并后的地址。
image.png
而经常出现的错误,也是在该过程中识别并报错的:
image.png

最后生成可执行程序。

如果有帮助,请三连 (⑅˃◡˂⑅)

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值