热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

C语言中程序编译系统的示例分析

这篇文章主要介绍C语言中程序编译系统的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!程序的翻译环境和执行环境

这篇文章主要介绍C语言中程序编译系统的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!

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

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

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

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

一个.c的文件事如何变成.exe的可执行文件的呢?下面这张图片是一个大概的过程:

C语言中程序编译系统的示例分析

编译和链接

翻译环境

C语言中程序编译系统的示例分析

  • 组成一个程序的每个源文件通过编译过程分别转换成目标代码( object code )。

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

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

编译的几个阶段

接下来,我来用Linux平台来给大家演示一下编译的三个过程:

我们先编写一个简单C程序:

C语言中程序编译系统的示例分析

然后执行这样一句指令:

gcc test.c

这句指令是让gcc这个编译器来编译我们的代码,执行完这句指令我们会发现会生成一个a.out这样一个可执行文件,

C语言中程序编译系统的示例分析

我们执行再下面这样一句指令:

./a.out

这样我们就可以执行这个可执行文件了,

C语言中程序编译系统的示例分析

为了让大家更好地感受到编译的过程,我们来一步一步看:

预处理

我们执行再下面这样一句指令,让代码预处理完之后就停下来:

gcc -E test.c -o test.i

这句指令的意思就是把预处理完之后的信息输出到一个test.i的文件中。

C语言中程序编译系统的示例分析

可以发现的是,这里多了一个test,i的文件,我们可以打开看一看:

C语言中程序编译系统的示例分析

可以发现的是,有三个点发生了变化:

  • 头文件被展开

  • 宏被文本替换了

  • 注释被删除了

我们对原代码做一个处理,不包含stdio.h的头文件,我们自己写一个头文件:

C语言中程序编译系统的示例分析

再来看一下,预处理后的文件是什么样子的:

C语言中程序编译系统的示例分析

效果通上面一样。

所以预处理的几个动作

  • 头文件的包含

  • 预处理指令的完成(eg:#define、#pragma…)

  • 注释的删除

编译

执行再下面这样一句指令让文件进行编译形成汇编代码:

gcc -S test.c

C语言中程序编译系统的示例分析

执行完之后就可以生产出一个test.s的文件,我们可以打开看一看:

C语言中程序编译系统的示例分析

这里其实就是汇编代码。

所以编译的几个动作

  • 语法分析

  • 词法分析

  • 语义分析

  • 符号汇总

符号汇总: 符号汇总的都是全局的符号。例如上面我们的代码头文件就汇总了一个Add,.c文件就汇总的一个Add和main。

汇编

接下来我们执行这样一条指令:

gcc -c test.c

对源文件进行汇编,结果生成了一个test.o的目标文件:

C语言中程序编译系统的示例分析

打开这个文件,我们会发现这是一个我们看不懂的二进制文件:

C语言中程序编译系统的示例分析

所以其实汇编是把汇编代码转换为二进制代码(机器指令)。

这个过程还做了一件件事——形成符号表

C语言中程序编译系统的示例分析

链接

链接做的两个事情

  • 合并段表

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

在Linux系统下,test.o二进制文件是用一个elf这样的格式来组织文件的。

elf会把文件组织成一个段。test.o和Add.o都有一个段,那么我们怎样才能看懂elf格式的文件呢?

我们有这样一个工具叫做readelf,他可以看懂这样一个文件,所以我们输入这样一条指令:

readelf test.o -a

C语言中程序编译系统的示例分析

我们就确实可以看到这样一个段的存在。

C语言中程序编译系统的示例分析

然后这下面还有符号表的汇总:

C语言中程序编译系统的示例分析

其实a.out这个文件也是elf格式的,所以其实链接就是把这几个elf格式的文件的段表合并,然后test中的Add函数就有了地址。

C语言中程序编译系统的示例分析

运行环境

程序执行的过程:

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

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

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

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

以上是“C语言中程序编译系统的示例分析”这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注编程笔记行业资讯频道!


推荐阅读
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • C# 7.0 新特性:基于Tuple的“多”返回值方法
    本文介绍了C# 7.0中基于Tuple的“多”返回值方法的使用。通过对C# 6.0及更早版本的做法进行回顾,提出了问题:如何使一个方法可返回多个返回值。然后详细介绍了C# 7.0中使用Tuple的写法,并给出了示例代码。最后,总结了该新特性的优点。 ... [详细]
  • Nginx使用AWStats日志分析的步骤及注意事项
    本文介绍了在Centos7操作系统上使用Nginx和AWStats进行日志分析的步骤和注意事项。通过AWStats可以统计网站的访问量、IP地址、操作系统、浏览器等信息,并提供精确到每月、每日、每小时的数据。在部署AWStats之前需要确认服务器上已经安装了Perl环境,并进行DNS解析。 ... [详细]
  • 本文介绍了Python高级网络编程及TCP/IP协议簇的OSI七层模型。首先简单介绍了七层模型的各层及其封装解封装过程。然后讨论了程序开发中涉及到的网络通信内容,主要包括TCP协议、UDP协议和IPV4协议。最后还介绍了socket编程、聊天socket实现、远程执行命令、上传文件、socketserver及其源码分析等相关内容。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 本文介绍了在rhel5.5操作系统下搭建网关+LAMP+postfix+dhcp的步骤和配置方法。通过配置dhcp自动分配ip、实现外网访问公司网站、内网收发邮件、内网上网以及SNAT转换等功能。详细介绍了安装dhcp和配置相关文件的步骤,并提供了相关的命令和配置示例。 ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 目录实现效果:实现环境实现方法一:基本思路主要代码JavaScript代码总结方法二主要代码总结方法三基本思路主要代码JavaScriptHTML总结实 ... [详细]
  • 阿,里,云,物,联网,net,core,客户端,czgl,aliiotclient, ... [详细]
  • Metasploit攻击渗透实践
    本文介绍了Metasploit攻击渗透实践的内容和要求,包括主动攻击、针对浏览器和客户端的攻击,以及成功应用辅助模块的实践过程。其中涉及使用Hydra在不知道密码的情况下攻击metsploit2靶机获取密码,以及攻击浏览器中的tomcat服务的具体步骤。同时还讲解了爆破密码的方法和设置攻击目标主机的相关参数。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 本文介绍了在Mac上搭建php环境后无法使用localhost连接mysql的问题,并通过将localhost替换为127.0.0.1或本机IP解决了该问题。文章解释了localhost和127.0.0.1的区别,指出了使用socket方式连接导致连接失败的原因。此外,还提供了相关链接供读者深入了解。 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
author-avatar
卫宇欢试试
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有