【C语言】程序运行过程:预处理/编译/汇编/链接

您所在的位置:网站首页 c语言代码生成流程图 【C语言】程序运行过程:预处理/编译/汇编/链接

【C语言】程序运行过程:预处理/编译/汇编/链接

2024-01-04 20:59| 来源: 网络整理| 查看: 265

文章目录 1.程序运行的几个阶段1.1预编译1.2编译1.3汇编1.4符号表和链接 2.运行环境结语 哈喽啊,盆友们。一起来看看 C语言中编译预处理的内容吧!😜

1.程序运行的几个阶段

众所不周知,C语言的程序运行分为几个阶段。

咱们可以看看下面这个图,简单了解一二👇

image-20220302105951684

细分开来,编译还分为3个小阶段:预编译(预处理)、编译、汇编

image-20220302110221434

这三个阶段又分别做了什么事情呢?这就需要我们用linux下的gcc编译器来验证了

1.1预编译

现在我们编写了一个这样的代码

image-20220302110948614

image-20220302111004125

在运行窗口中输入以下指令,进行预编译操作,得到test.i文件

gcc -E test.c -o test.i

image-20220302111042754

打开该文件,滑倒最底部,查看它与源代码的不同

image-20220302111224560

可以发现以下几点:

头文件消失:实际上被展开了注释被删除define定义的符号被替换

这就是预编译阶段做的3件事,实际上都是一些文本操作,并没有运行该代码

1.2编译

输入以下指令,生成test.s文件

gcc -S test.i -o test.s

image-20220302111725318

打开该文件,发现我们好像看不太懂它里面写了些什么

image-20220302111848369

实际上,mov、sub都是汇编语言,这一步就是把C语言代码转变成了汇编代码。 进行了以下几步操作:

语法分析词法分析语义分析符号汇总

image-20220302112256166

这一部分内容可以阅读《程序员的自我修养》这本书,记录一下

1.3汇编 gcc -c test.s -o test.o

image-20220302112625672

这个指令会生成一个test.o目标文件

Linux:目标文件后缀为.oWindows:目标文件后缀为.obj

.o目标文件和可执行成句的文件格式elf

readelf工具可以解析elf格式的文件

用文本编辑器打开这个文件,可以看到里面的东西都是乱码

image-20220302112532139

实际上这个文件里面存放的是二进制内容。

汇编操作就是将汇编代码转换成二进制指令

其中有非常重要的一部:形成符号表

1.4符号表和链接

这个代码中其实包含了两个源文件:test.c、Add.c

image-20220302113122577

里面出现了两个符号,main和Add

编译器会先对每个源文件创立一个符号表,为它们添加一个类似地址的参数。在链接阶段的时候,相同符号的地址参数会被设置为一样的

这里编译会查看Add函数的定义在哪里

如main函数中只是extern,并没有Add的具体实现,最后链接之时,Add符号的地址会被设置为Add.c中该符号的地址

这个操作又叫:符号表的合并和重定位

链接阶段还会执行另外一个操作:合并段表

gcc test.o add.o -o test //生成可执行程序test

image-20220302113722693

使用./TEST操作执行该文件,可以看到程序成功输出了Add后的答案

image-20220302113738246

2.运行环境

程序执行的过程中:

程序先载入内存。在操作系统中,这个操作由系统完成;在独立环境中,程序的载入必须手动完成,也可以是通过可执行代码置入只读内存来完成程序执行开始。调用main函数开始执行代码。这时将使用一个运行时堆栈(stack),存储函数的局部变量和返回地址。程序同时使用静态内存,存储于静态内存中的变量在程序的整个执行过程中保留它们的值终止程序。正常终止main函数,也可能是意外终止 结语

本篇博客中,我们认识了解了程序运行的几个阶段。这里面还有很多更深层次的问题待我去探究。

下篇博客:预处理详解

点个赞再走呗,谢谢!



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3