| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> C++知识库 -> 从0开始学c语言-39-程序环境(翻译环境和执行环境的简单介绍) -> 正文阅读 |
|
[C++知识库]从0开始学c语言-39-程序环境(翻译环境和执行环境的简单介绍) |
上一篇:从0开始学c语言-38-题目练习_阿秋的阿秋不是阿秋的博客-CSDN博客 ????????说起来,你有没有想过你写的程序是如何运行起来并让你看到结果的? ? ? ? ? 这一篇,我们就学这个。但是说实话,这个运行过程通过vs编译器去实现不够细节,所以主要展示了liux环境(在总结处放上了学习VIM的学习链接)。 目录 1. 程序的翻译环境和执行环境????????在ANSI C的任何一种实现中,存在两个不同的环境。
2. 详解编译+链接2.1 翻译环境首先写一段简单的代码,
?????????运行后,我们可以看到,生成了一个后缀为(.exe)的文件,这个文件就是我们说的可执行程序,也是通过翻译环境后的成果。 ? ? ? ? 这里画个图示意一下翻译过程。总的来说,翻译环境分为两大部分:编译和链接。而编译对应的就是把源文件生成目标文件,编译依赖的是编译器(就是cl.exe,可在安装目录中寻找),链接依赖的是链接器(link.exe)。 ? ? ? ? ?
????????这里链接库需要介绍一下,比如我们用到了printf函数,它所对应的静态库(.lib)就是我们的链接库。 ? 2·2编译? ? ? ???????????????????编译环节分为三步:预编译(预处理)、编译、汇编。 先写一段代码
? ? ? ? 运行代码后,默认生成一个a.out的可执行程序。可以输入./a.out可以运行这个程序,得到程序执行结果。(
注:生成可执行程序意味着是经过了链接器链接的,不要被标题影响,这里只是引导
。)
为了看到编译中每一步的细节,可以用以下指令:
预处理????????为了能够把每一步产生的结果分开,便每次保存到不同的文件中。 比如:输入 gcc test.c - E > test.i 这个意思就是把预处理产生的结果放在test.i文件中。 ? ? ? ? 打开文件如图。 ?????????你会发现前面的一些东西你可能看不懂,但是留意一下这些名称。 ????????在观察一下,这些词似乎被(stdio.h)包含着。通过指令,可以看到我们引用的头文件。 ?????????打开后,可以找到我们刚刚看不懂的名词。 ?????????所以我们引用头文件的时候,就是把头文件的内容拷贝过来。 预处理阶段:
????????这个文件的含义同原本的文件无异,只是内容上有所不同。 编译这个在《编译原理》中介绍很详细。
????????这个文件中放的是汇编代码,所以编译后产生了汇编代码。 ????????将预处理完的文件逐一进行一系列词法分析、语法分析、语义分析及优化后,产生相应的汇编代码文件(符号汇总)。编译是针对单个文件编译的,只校验本文件的语法是否有问题,不负责寻找实体。 汇编
????????把汇编代码转换成机器指令(二进制指令),这个阶段生成符号表 ,同样也不是你肉眼就能看懂的文件,test.o文件是elf格式的文件,可以用readlf文件查看。??test.o把文件内容划分为不同的段,每个段中存放的数据不同。? ? ? ????????生成的符号表(test.o) 用readlf文件查看,可以看到把编译阶段汇总的符号表(汇总了全局符号)进行了符号表的生成。 ?????????为了更加理解符号表,我们用这样一段代码进行阐述。 ? ? ? ? 画个图示意一下吧。经过编译汇总的符号不会包含局部符号,因为局部符号只有进入函数后才会生成。经过汇编后,对前面汇总的符号生成对应的符号表。而这个符号表就是我们所谓的test.o(类似test.obj)的目标文件。 ? ????????在目标文件中可以查到我们的符号,可以看到在add.o文件中确实可以看到Add符号。 2·3 链接????????在链接阶段把多个目标文件和链接库进行链接,主要完成了两件事:
?1·合并段表 ????????你可能不知道段表是什么,别忘了之前我们曾说过,是什么文件对数据进行了分段处理呢?
????????而我们现在是有两个源文件的,那么会生成两个后缀为(.o)的文件。这两个文件都会进行分段,而合并段表就是把相同段的数据进行合并,合并为一个a.out文件(也是elf格式的文件,意味着可以用readlf文件查看),其实就是我们的可执行程序(.exe)。 2·符号表的合并和重定位 ????????我们知道现在有两个符号表,因为在test.c文件中只有ADD的声明,所以它的地址并没有什么实际意义。所以在进行符号表的合并和重定位的时候,我们选择了add.c文件所生成的Add符号。 ????????(简单来说,进行了符号表的合并,选择了有效符号)。 ?????????那么在程序执行的时候,就可以通过符号表上的地址找对应的函数。 ? ? ? ? 有可能现在感受不到这些过程有什么用,但实际上这些过程对于这个程序能否正常运行是十分重要的。正是因为有了符号表,才可以实现跨文件使用函数的操作。 宏观来说:
????????到此,翻译环境的编译和链接两个部分就介绍完了,想知道更多,请看《程序员的自我修养》。 总结翻译环境:从源文件变到可执行程序,经过两步:编译、链接。 编译:分为三步,预处理、编译、汇编
链接:合并段表(可执行程序,其实就是生成了test.exe)、符号表的合并和重定位。 提示:以上内容如果想复现,请学习VIM、gcc或者linux。
3·运行环境(执行环境)
程序执行的过程:
????????1. 程序必须
载入内存中
。
????????2. 程序调用
main
函数。
????????3. 开始执行程序代码。
????????4. 终止程序。正常终止
main
函数;也有可能是意外终止(比如你写错代码了)。
|
|
C++知识库 最新文章 |
【C++】友元、嵌套类、异常、RTTI、类型转换 |
通讯录的思路与实现(C语言) |
C++PrimerPlus 第七章 函数-C++的编程模块( |
Problem C: 算法9-9~9-12:平衡二叉树的基本 |
MSVC C++ UTF-8编程 |
C++进阶 多态原理 |
简单string类c++实现 |
我的年度总结 |
【C语言】以深厚地基筑伟岸高楼-基础篇(六 |
c语言常见错误合集 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年1日历 | -2025/1/11 12:42:26- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |