[C++]HelloWorld背后的故事!总结一下在我们运行exe可执行文件前究竟发生了什么!

人物介绍

姓名 HelloWorld
性别 .cpp
住址 D:\
身份证号(SHA1) 25106D2879A9EA300BB264F8155A71D7C44DA2E8

故事简介

  1. 编写源文件
  2. 预编译
  3. 编译
  4. 汇编
  5. 链接

一、编写源文件

??源代码:

#include <iostream>
using namespace std;

int main()
{
	cout << "Hello World!" << endl;
	return 0;
}

二、预编译

??预编译输入命令g++ -o HelloWorld.i -E HelloWorld.cpp

??该命令表示编译环节的第一步,也就是预编译!当然,这一步也可以被称为“编译预处理”!而这个 HelloWorld.i 即是预编译过后的文件!

序号 主要行为
1. 展开所有的宏定义,消除“#define”
2. 处理所有的预编译指令,比如#if、#ifdef等
3. 处理#include预编译指令,将包含文件插入到该预编译的位置
4. 删除所有的注释“/**/”、"//"等
5. 添加行号和文件名标识,以便于编译时编译器产生调试用的行号信息以及错误提醒
6. 保留所有的#program编译指令,原因是编译器要使用它们

值得注意:这一步不会做出任何安全性和合法性的检查!

三、编译

??编译请输入命令g++ -o HelloWorld.s -S HelloWorld.i

??该命令表示编译过程,也就是生成相应的汇编文件 HelloWorld.s 。

主要行为 具体描述
词法分析 将源代码文件的字符序列划分为一系列的记号,一般词法分析产生的记号有:标识符、关键字、数字、字符串、特殊符号(加号、等号);在识别记号的同时也将标识符放好符号表、将数字、字符放入到文字表等;有一个lex程序可以实现词法扫描,会按照之前定义好的词法规则将输入的字符串分割成记号,所以编译器不需要独立的词法扫描器
语法分析 语法分析器将对产生的记号进行语法分析,产生语法树----就是以表达式尾节点的树,一步步判断如何执行表达式操作;如果存在括号不匹配或者表达式错误,编译器就会报告语法分析阶段的错误;相同的存在一个yacc程序可以根据用户输入的语法规则生成语法树;
语义分析 由语法阶段完成分析的并没有赋予表达式或者其他实际的意义,比如乘法、加法、减法,必须经过语义阶段才能赋予其真正的意义;
代码优化 将代码进行优化处理
符号汇总 汇总所有符号

补充说明:其中语义分析又可以分为“静态语义分析”和“动态语义分析”两种。

语义分析 简单说明
静态语义分析 通常在编译器就可以确定的语义,主要包括“声明”、“类型的匹配”以及“类型的转换”
动态语义分析 只能在运行期才能确定的语义

四、汇编

??汇编请输入命令g++ -o HelloWorld.o -C HelloWorld.s

??该命令表示对 HelloWorld.s 文件进行汇编处理,生成对应的可重定位的二进制文件 HelloWorld.o ,也就是我们所熟知的机器语言对应的文件。

五、链接

??链接请输入命令g++ HelloWorld.cpp -o HelloWorld.exe

??通过调用链接器ld来链接程序运行需要的一大堆目标文件,以及所依赖的其它库文件,最后生成可执行文件., 链接的主要内容是把各个模块之间相互引用的部分处理好,使得各个模块之间能够正确地衔接。

需要指出:链接分为“静态链接”和“动态链接”。

链接类型 具体说明
静态链接 指在编译阶段直接把静态库加入到可执行文件中去,这样可执行文件会比较大
动态链接 指链接阶段仅仅只加入一些描述信息,而程序执行时再从系统中把相应动态库加载到内存中去

需要补充:

库文件类型 特点
静态库文件 是一个二进制文件,存放的功能函数实现,在文件编译时要访问文件,编译之后静态库文件可以删除
动态库文件 是一个二进制文件,存放的功能函数实现,在文件执行时要访问文件,编译时不需要动态库文件

额外说明:

操作系统 动态库文件后缀名
linux .so
window .dll

相册

预编译后的文件HelloWorld.i

??可以看到,代码量惊人的大!足足有两万多行!可想这个HelloWorld也不简单啊!

编译后的文件HelloWorld.s

??很明显看出,此时代码精简了很多!

汇编后的文件HelloWorld.o

??可以看出,记事本已经显示乱码了!

帮忙的朋友

工具 作用 负责过程
编辑器 编写代码的一些窗口 编写源代码
编译器 检查用户代码的一些语法错误,将其编译成汇编代码 预编译、编译
汇编器 将编译出来的汇编文件编译成一定功能的目标代码 汇编
连接器 将目标代码连接成可执行文件 链接

原创说明

原文作者:Seaver(海之恋SF)

如要转载,请务必注明出处!

原文链接:https://www.cnblogs.com/seafever/p/12577337.html

原文地址:https://www.cnblogs.com/seafever/p/12577337.html

时间: 2024-10-07 12:33:04

[C++]HelloWorld背后的故事!总结一下在我们运行exe可执行文件前究竟发生了什么!的相关文章

你好,C++(4)2.1.3 我的父亲母亲:编译器和链接器 2.1.4 C++程序执行背后的故事

2.1.3  我的父亲母亲:编译器和链接器 从表面上看,我是由Visual Studio创建的,而实际上,真正负责编译源代码创建生成可执行程序HelloWorld.exe的却是Visual Studio中集成的C++编译器cl.exe和链接器link.exe.他们二老,才是我的亲生爹妈. 为了便于人们的编写.阅读和维护,我们的源文件是使用C++这种人们可以理解的高级程序设计语言编写的.然而,计算机却并不理解这种高级语言,也就无法直接执行高级语言编写而成的源文件.所以,这里就需要一个翻译的工作,将

(转载)你好,C++(4)2.1.3 我的父亲母亲:编译器和链接器 2.1.4 C++程序执行背后的故事

你好,C++(4)2.1.3 我的父亲母亲:编译器和链接器 2.1.4 C++程序执行背后的故事 2.1.3  我的父亲母亲:编译器和链接器 从表面上看,我是由Visual Studio创建的,而实际上,真正负责编译源代码创建生成可执行程序HelloWorld.exe的却是Visual Studio中集成的C++编译器cl.exe和链接器link.exe.他们二老,才是我的亲生爹妈. 为了便于人们的编写.阅读和维护,我们的源文件是使用C++这种人们可以理解的高级程序设计语言编写的.然而,计算机却

图像处理界的标准图像Lena背后的故事

今天晚上实验室的哥们问到我:“蒋志强,你知道咱们数字图像处理界标准图像Lena吗?” “当然知道啊,不就是那个512×512的美丽姐姐的标准图像么?”我不以为然的回答: “那幅图像事实上不是原始图像?”我哥们纠正我的说法: “真的么?”我非常怀疑的问道: “那事实上仅仅是原图的截图”哥们严肃认真的解释道: 数字图像处理界的标准图像Lena: 强烈的好奇心驱始我上网搜索,关于Lena的故事,结果让我大吃一惊,更确切的说是让我笑得肚子都痛了.独自乐乐不如众乐乐. 图片中的女孩全名Lena Soder

Mac OS X 背后的故事

Mac OS X 背后的故事 作者: 王越  来源: <程序员>  发布时间: 2013-01-22 10:55  阅读: 25840 次  推荐: 49   原文链接   [收藏] 作者王越,美国宾夕法尼亚大学计算机系研究生,中国著名 TeX 开发者,非著名 OpenFOAM 开发者. Mac OS X 背后的故事(一)力挽狂澜的Ellen Hancock Mac OS X 背后的故事(二)Linus Torvalds的短视 Mac OS X 背后的故事(三)Mach之父Avie Tevan

联想手机#P1来了#P1背后的故事系列

http://bbs.lenovo.com/forum.php?mod=viewthread&fid=928&tid=560992&extra=page%3D1 本帖最后由 奔在旅途的小草 于 2015-8-28 15:48 编辑 P1发布在即研发.产品经理.项目经理大大们呕心沥血一款牛逼的产品即将面世 你是否想了解更多P1背后的故事呢?你想知道为什么电池是5000毫安而不是6000毫安呢?你是否想知道P1命名的由来? 小草故事精粹将跟大家分享——P1背后的故事做客嘉宾:@做机的A

【系统篇】从C/C++语言到进程启动背后的故事

我们需要运行一个程序或者软件,双击之即可完成.不过从你双击到程序的窗口产生的这“短暂”的时间内,Windows为你做了很多的工作. 首先,系统有一个进程监测到了你的双击操作,这个进程就是系统shell,没错,就是资源管理器explorer.exe,不是IE浏览器了,那是另一个进程IExplorer.exe.你可以尝试打开任务管理器将这个进程结束掉,然后桌面的一切元素都没有了,任务栏,图标什么的都消失了.只剩下墙纸一张,此时,右键菜单也不复存在···因为平时负责这些东西的explorer.exe已

?Uber新Logo背后的故事:二进制和原子带来灵感

Uber更换新Logo意味着公司品牌的全面改变 凤凰科技讯 北京时间2月4日消息,打车应用Uber最近启用全新Logo,看起来只是一个不经意的举动,实则饱含了Uber创始人.CEO特拉维斯·卡兰尼克(Travis Kalanick)无数的心血.Logo的改变意味着品牌的改变,而一切改变都是为了更好的增长.新Logo是怎么诞生的呢?背后的故事可是一言难尽. 最近<连线>杂志刊文披露了这一历程,凤凰科技挑选了重要内容为大家呈现: 彩色图标欢迎您 今天,当许多人掏出智能手机,在屏幕上寻找黑白Uber

using关键字背后的故事!

using关键字的作用: 1:可以引入命名空间2:可以释放资源 *****不能使用using语句完全替换掉(try-catch-finally)语句(无法进行异常处理) 在出了using语句的{}后,系统会自动释放资源(系统自动调用了Dispose()方法)而在Dispose方法中是这么实现的 3:哪些对象可以被using语句回收掉呢?必须实现了IDisposable接口的类型才可以被using语句引用! 4:IDisposable接口的Dispose()方法背后的故事! 接口中的Dispose

(转载)你好,C++(25)函数调用和它背后的故事5.1.2 函数调用机制

你好,C++(25)函数调用和它背后的故事5.1.2 函数调用机制 5.1.2  函数调用机制 在前面的学习中,我们多次提到了“调用函数”的概念.所谓调用函数,就是将程序的执行控制权从调用者(某个函数)交给被调用的函数,同时通过参数向被调用的函数传递数据,然后程序进入被调用函数内部,执行函数定义中的代码获得结果数据,函数体代码执行完毕后再将控制权交回给调用者同时将结果数据通过返回值传递给调用者,作为整个函数调用表达式的值.简而言之,调用函数也就是执行函数中的代码,完成函数的功能. 在学习如何编写