【C进阶】程序的环境

简介: 目录1、引言2、翻译环境 (一)编译 (1)预处理 (2)编译环节 (3)汇编 (二)链接3、运行环境

1、引言

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


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

第2种是执行环境,它用于实际执行代码

比如说我们写了一个源文件test.c,其经过一个详细的处理后会变成test.exe文件,此篇文章会详细讲解test.c文件是如何到test.exe文件的,其实主要有两个大的过程,1是编译,2是链接。而此过程所依赖的主要环境就是翻译环境,而test.exe文件想运行起来所依赖的环境是运行环境。


正文开始:

2、翻译环境

先看一幅图:image.png假设我们在一个工程里面写了test.c,contact.c,common.c这三个源文件。每一个.c文件都会经过编译器处理,最后各自生成一个目标文件(windows底下以.obj作为后缀),这些目标文件和链接库一起经过链接器最后生成可执行程序。image.png组成一个程序的每个源文件通过编译过程分别转换成目标代码(object code)。

每个目标文件由链接器(linker)捆绑在一起,形成一个单一而完整的可执行程序。

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

解释第3条:(用printf举例)

image.png Libraries就是库,printf就是包含在以后缀.LIB命名的静态库里头。要使用pritnf,就应该把这些.LIB文件的链接库链接进来

  • 而编译又可分为以下三个部分(用一张图先过渡下)image.png下面将会详细介绍一个源文件是如何到可执行程序的。

(一)、编译

  • 先看一段代码:
#include<stdio.h>
int g_val = 2021;
int Add(int x, int y)
{
  return x + y;
}
int main()
{
  int a = 10;
  int b = 20;
  int ret = Add(a, b);
  printf("%d\n", ret);
  return 0;
}

在VS环境中,我们执行该程序需要按ctrl+F5,但是此时会直接生成可执行程序,无法看到具体转换过程,所以采用linux可以很好的观察到这一现象:即将编译拆分成预处理+编译+汇编


注意:

在linux环境中,如果直接使用gcc来编译test.c文件,它默认生成一个a.out的一个文件,该文件同样也是个可执行程序,为了避免和VS环境一样直接生成可执行程序而无法观察到细节,因此我们需要在预处理后停下来,编译后停下来,汇编后停下来。操作如下:


1. 预处理 选项 gcc -E test.c -o test.i


预处理完成之后就停下来,预处理之后产生的结果都放在test.i文件中。


2. 编译 选项 gcc -S test.c


编译完成之后就停下来,结果保存在test.s中。


3. 汇编 gcc -c test.c


汇编完成之后就停下来,结果保存在test.o中。


具体过程见下文:

(1)预处理

在linux环境中使用gcc test.c -E这个选项来编译test.c文件,就可以使其预处理后停下来


而这个命令执行后,会出现一堆代码,此时我们再使用gcc -test.c -E > test.i这个操作就可以把出现的一堆代码重定向输出到test.i文件里头,打开test.i文件


先看三幅图:


图一:

image.png

  • 图二:

此时我们在test.c文件里头添加些宏定义,再和预处理阶段对比看看:image.png

  • 图三:

当我们在test.c文件中加上一些注释时,在预处理阶段又会发生什么呢?image.png通过上述三张图:可以总结出在预处理阶段的3条结论:

完成了头文件的包含

#define定义的符号和宏的替换

注释删除

而上述三个操作都属于文本操作。

(2)编译环节

在经过上述的预处理后,就来到了编译环节:


我们使用gcc test.i -S这个指令进行编译,最终生成test.s文件,我们打开test.s文件来看看:


先简单截取一段:image.png上述代码即汇编代码,综上可得出结论:


汇编过程即把C语言代码转化成汇编代码,主要做了以下4个内容:

语法分析

词法分析

语义分析

符号汇总

先简单解释下符号汇总:

把全局变量和函数名汇总起来,比如main和全局变量g_val,符号汇总的用处是在下一阶段汇编和链接中体现出来的,下文会详细介绍:


简单举一例:image.png(3)汇编

在我们编译结束后生成了test.s文件,接下来进入汇编


我们使用gcc test.s -c命令进行汇编,最后生成test.o这样的一个文件,而这个test.o文件就类似于windows上的test.obj文件,即生成了目标文件。我们打开test.o文件:(简单截取一段)

image.png上图中放的其实都是二进制信息。由此得到汇编的结论:

  1. 把汇编代码转换成机器指令(二进制指令)
  2. 形成符号表

而汇编中的生成符号表和编译中的符号汇总又有什么关联呢?接下来详细介绍:

  • 重新举个例子:

如图所示,我们创建了add.c和test.c两个源文件image.png 在linux环境中,test.c文件和add.c文件会经过预处理、编译、汇编生成对应的test.o文件和add.o文件。

而汇编中的形成符号表其实就是有一张表格,里面既有汇总的符号,也有这些符号对应的地址

  • 拿上例说明:image.png注:

test.c汇总的Add符号由于Add是声明的,找不到确切的地址,所以用红色记号笔简要表示。


理解了符号表,当生成.o文件(目标文件)时,多个.o文件经过连接器链接会生成可执行程序即test.exe文件。这个过程链接就起到了主要作用,详解见下文:


(二)、链接

链接主要实现的操作有两个:

合并段表

符号表的合并和符号表的重定位

如上图test.c文件和add.c文件会经过预处理、编译、汇编生成对应的test.o文件和add.o文件。而它俩要链接在一起,首先就要发生合并段表。


合并段表:

像add.o这样的文件是有它字节的格式的,它会把自己分成几个段。自然test.o也会这么分,两个段的格式是一样的,只不过内容是不一样的。而合并段表就是把对应的段上的数据合并在一起,如图:

image.png注:这些段表的格式都是elf文件格式

符号表的合并和符号表的重定位:


image.png

在上述两个操作执行完毕后,就可生成可执行程序了,此时整个翻译环境就讲解完毕。


3、运行环境

程序执行的过程:

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

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

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

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


相关文章
|
小程序 JavaScript 前端开发
小程序云开发全套实战教程(最全)
小程序云开发全套实战教程(最全)
145 0
|
Linux 数据安全/隐私保护 Windows
jupyter环境下从零模拟开发简易操作系统: 搭建一个学习ucore_OS学习的环境(第二节)
上一节已经一万字了,只好再加一节 如果想要直接 体验 实验效果 可以直接执行本章的命令 生成的img文件可以在qemu中正常运行的话,那么在 真实硬件上基本 也是可以 正常安装操作系统
58 1
|
小程序 前端开发 JavaScript
小程序的入门
小程序的入门
74 0
|
算法 C语言 C++
04 C++ - 入门程序
04 C++ - 入门程序
48 0
|
JSON 小程序 JavaScript
小程序入门
小程序入门
183 0
|
Ubuntu Linux iOS开发
搭建Python开发环境详细步骤
搭建Python开发环境详细步骤
383 0
|
机器学习/深度学习 Ubuntu Java
新手入门指南之玩转蓝桥云课(线上运行虚拟机,c++,Java,Javaweb,python环境,以及如何成功利用命令行运行这些环境)(1)
新手入门指南之玩转蓝桥云课(线上运行虚拟机,c++,Java,Javaweb,python环境,以及如何成功利用命令行运行这些环境)(1)
1842 0
新手入门指南之玩转蓝桥云课(线上运行虚拟机,c++,Java,Javaweb,python环境,以及如何成功利用命令行运行这些环境)(1)
|
机器学习/深度学习 IDE 前端开发
新手入门指南之玩转蓝桥云课(线上运行虚拟机,c++,Java,Javaweb,python环境,以及如何成功利用命令行运行这些环境)(2)
新手入门指南之玩转蓝桥云课(线上运行虚拟机,c++,Java,Javaweb,python环境,以及如何成功利用命令行运行这些环境)(2)
1589 0
新手入门指南之玩转蓝桥云课(线上运行虚拟机,c++,Java,Javaweb,python环境,以及如何成功利用命令行运行这些环境)(2)
|
安全 IDE 搜索推荐
安卓开发从源码看后端技术——搭建环境与断点调试
今天就让我们开启源码共读的篇章吧,希望这不同的眼界探索可以在这截然不同的领域会有所收获,为自身技术带来启发。
328 0
|
存储 大数据 网络安全
环境介绍|学习笔记
快速学习环境介绍
环境介绍|学习笔记