编译和连接

目录
  1. 翻译环境和运行环境
  2. 翻译环境:预编译+编译+汇编+链接

1. 翻译环境和运行环境

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

 (1) 翻译环境,在这种环境中源代码被转换为可执行的机器指令(二进制指令)。

 (2) 执行环境,它用于实际执行的代码。

2. 翻译环境

翻译环境是怎么将源代码转换为可执行的机器指令?翻译环境大概所做的事情:

编译和链接两个过程组成,而编译又可分为预处理(预编译)、编译、汇编三个过程。

一个C语言的项目中可能有多个 .c 文件一起构建,那多个 .c 文件如何生成可执行程序?

(1) 多个 .c 文件单独经过编译器,编译处理生成对应的目标文件。

(2) 注: 在windows环境下的目标文件的后缀是 .obj,Linux环境下目标文件的后缀是 .o.

(3)多个目标文件和链接库一起经过链接器处理生成最终的可执行程序。

(4)链接库是指运行时库(它是支持程序运行的基本函数集合)或者第三方库。

编译器的过程(如图):

2.1 预处理(预编译)

在预处理阶段,源文件和头文件会被处理为 .i 后缀的文件。

在gcc 环境想观察一下,对 test.c 文件与处理后的文件,命令如下:

gcc -E test.c -o test.i

预处理阶段主要处理那些源文件中#开始的预编译指令。比如: #include,#define,处理规则如下:

 将所有的 #define删除,并展开所有的宏定义。

 处理所有的条件编译指令,如: #if、#ifdef、#elif、#else、#endif。

 处理#include预编译指令,将包含的头文件的内容插入到该预编译指令的位置。这个过程是递归进行的,也就是说被包含的头文件可能包含其他文件。

 删除所有的注释

 添加行号和文件标识名,方便后续编译器生成调试信息等。

 或保留所有的#pragma的编译器指令,编译器后续会使用。

经过预处理后的 .i文件不再包含宏定义,因为宏已经被展开。并且包含的头文件都被插入 .i 文件中。所以我们无法知道宏定义或者头文件是否包含正确的时候,可以查看与处理后的 .i 文件来确认。

2.2 编译

编译过程就是将与预处理后的文件进行一系列的: 词法分析、语法分析、语义分析及优化,生成相应的汇编代码文件。

编译过程的命令如下:

gcc -S test.i -o test.s

读下面的代码进行编译的时候,会怎么做?

array[inedx]=(index+4)*(2+6);

 2.2.1 词法分析

将源代码程序被输入扫描器,扫描器的任务就是简单的进行词法分析,将代码中的字符分割成一系列的记号(关键字、标识符、字面量、特殊字符等)。

上面分析进行词法分析后得到16个记号:

2.2.2 语法分析

语法分析器,将扫描产生的记号进行语法分析,从而产生语法树。这些语法是以表达式为节点的数。

                                                           语法树

2.2.3 语义分析

由语义分析器来完成语义分析,即对表达式的语法层面的分析。编译器所能做的分析就是语义的静态分析。静态语义分析包括声明和类型的匹配,类型的转换等。这个阶段会报告错误的语法信息。

2.3汇编

汇编器将汇编代码转换变成机器可执行的指令,每一个汇编语句几乎对应一条机器指令。就是根据汇编指令和机器指令的对照表一一的进行翻译,也不做优化。

汇编命令如下:

gcc -c test.s -o test.o

2.4 链接

链接是一个复杂的过程,链接的时候需要把一堆文件链接在一起才生成可执行的程序。

链接过程主要包括: 地址和空间分配,符号决议和重定位等步骤。

链接解决的是一个项目中多文件、多模块之间互相调用的问题。

比如:

在一个c项目中有2个文件(test.c)和(add.c),代码如下:
 

extern Add(int x, int y);//声明外部函数
int main()
{
	int a = 10;
	int b = 20;
	int r = Add(a, b);
	printf("%d", r);
	return 0;
}
#define _CRT_SECURE_NO_WARNINGS 1
int Add(int x, int y)
{
	return x + y;
}

 test.c经过编译器处理生成 test.o

 add.c经过编译器处理生成 add.o

3. 运行环境

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

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

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

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

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/704293.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

PostgreSQL 多表连接不同维度聚合统计查询

摘要:在本文中,你将学习到如何使用 PostgreSQL 完全外连接,从两个或多个表中聚合维度统计数据。 文章目录 一、常用的连接类型图示二、数据库表设计示例三、连接查询示例1. inner join 内连接(不能满足维度统计需求)2. full join 完全外连接(满足维度统计需求)一、常用的…

Golang免杀-分离式加载器(传参)AES加密

目录 enc.go 生成: dec.go --执行dec.go...--上线 cs生成个c语言的shellcode. enc.go go run .\enc.go shellcode 生成: --key为公钥. --code为AES加密后的数据, ----此脚本每次运行key和code都会变化. package mainimport ("bytes""crypto/aes"&…

java1.8运行arthas-boot.jar运行报错解决

报错内容 输入java -jar arthas-boot.jar,后报错。 [INFO] JAVA_HOME: D:\developing\jdk\jre1.8 [INFO] arthas-boot version: 3.7.2 [INFO] Can not find java process. Try to run jps command lists the instrumented Java HotSpot VMs on the target system.…

Spring Boot集成antlr实现词法和语法分析

1.什么是antlr? Antlr4 是一款强大的语法生成器工具,可用于读取、处理、执行和翻译结构化的文本或二进制文件。基本上是当前 Java 语言中使用最为广泛的语法生成器工具。Twitter搜索使用ANTLR进行语法分析,每天处理超过20亿次查询&#xff1…

20240612在飞凌的OK3588-C开发板的linux系统下测试以太网

20240612在飞凌的OK3588-C开发板的linux系统下测试以太网 2024/6/12 17:56 欢迎您入坑飞凌的OK3588-C开发板,使用飞凌的预编译的固件:OK3588-linuxfs-img.tar.bz2 Z:\rockdev\update.img tar jxvf OK3588-linuxfs-img.tar.bz2 首先,刷Android…

自己用pip下载好模块啦,但是在pycharm里面不显示?

问题: 今天在cmd里面用pip命令安装第三方模块,最后用pip list 命令发现已经成功安装,但是在pycharm里面用该模块的时候,还是爆红,显示没有该库 。 解决方法: 第一种(项目刚创建)&am…

虚拟声卡实现音频回环

虚拟声卡实现音频回环 一、电脑扬声器播放声音路由到麦克风1. Voicemeeters安装设置2. 音频设备选择 二、回声模拟 一、电脑扬声器播放声音路由到麦克风 1. Voicemeeters安装设置 2. 音频设备选择 以腾讯会议为例 二、回声模拟 选中物理输入设备“Stereo Input 1”和物理输出设…

GUI listbox

GUI listbox (自用笔记) 功能details拆分 同时打开多个文件,可以是不同类型的,在listbox中显示出路径和文件名; 计算每个数据文件(.txt或.dat)掉帧出现的行数,存储到元胞数组&…

Vue10-事件修饰符

一、示例&#xff1a;<a>标签不执行默认的跳转行为 1-1、方式一 <a href"http://www.baidu.com" onclick"event.preventDefault();">点击我</a> 1-2、方式二 1-3、方式三&#xff1a;事件修饰符 二、Vue的六种事件修饰符 2-1、prevent&…

今日早报 每日精选15条新闻简报 每天一分钟 知晓天下事 6月13日,星期四

每天一分钟&#xff0c;知晓天下事&#xff01; 2024年6月13日 星期四 农历五月初八 1、 财政部&#xff1a;将在19日第一次续发行2024年20年期超长期特别国债。 2、 成本低&#xff0c;商载高&#xff0c;我国自主研制HH-100商用无人运输机首飞成功。 3、 四川甘孜州石渠县1…

Mongodb在UPDATE操作中使用$pull操作

学习mongodb&#xff0c;体会mongodb的每一个使用细节&#xff0c;欢迎阅读威赞的文章。这是威赞发布的第68篇mongodb技术文章&#xff0c;欢迎浏览本专栏威赞发布的其他文章。如果您认为我的文章对您有帮助或者解决您的问题&#xff0c;欢迎在文章下面点个赞&#xff0c;或者关…

网站线上模板建设的优缺点

优点&#xff1a; 1.搭建的时间短&#xff0c;在线建站&#xff0c;只需要登录注册然后选择网站模板创建网站即可管理自己的网站后台&#xff0c;就几步操作就可以实现。 2.网站出错率少&#xff0c;因为有很多用户在使用&#xff0c;前期所报出来的问题就已经一一…

PHP开发的爱情盲盒交友系统网站源码

源码介绍 PHP开发的爱情盲盒交友系统网站源码 独立后台 源码截图 源码下载 PHP开发的爱情盲盒交友系统网站源码

【Tkinter界面】Canvas 图形绘制(03/5)

文章目录 一、说明二、画布和画布对象2.1 画布坐标系2.2 鼠标点中画布位置2.3 画布对象显示的顺序2.4 指定画布对象 三、你应该知道的画布对象操作3.1 什么是Tag3.2 操作Tag的函数 https://www.cnblogs.com/rainbow-tan/p/14852553.html 一、说明 Canvas&#xff08;画布&…

【高频】从准备更新一条数据到事务的提交的流程描述

一、相关问题 SQL语句是如何被MySQL解析和分析的?MySQL是如何为SQL语句生成最优的执行计划的?执行计划的各个步骤是如何一步步执行的?MySQL是如何访问存储引擎得到数据的&#xff1f;MySQL是如何将查询结果返回给客户端的?MySQL是如何处理事务的&#xff1f; 参考回答&am…

【Spine学习01】之基本操作

Spine简单讲就是做动画的&#xff0c;跟PS配合使用 左键单击选择 双颊取消选择 右键移动视图 右键单击移动变换 crtly重做 c 旋转 v 移动 x 缩放 z 倾斜 教程看的是B站的断断子老师&#xff0c;这个专栏用来放的是本人的学习笔记。

如何对stm32查看IO功能。

有些同学对于别人的开发板的资源&#xff0c;或者IO口&#xff0c;或者串口等资源不知道怎么分配。 方法1、看硬石、野火、正点原子的开发板&#xff0c;看下他们的例子&#xff0c;那个资源用什么。自己多看几个原理图&#xff0c;多看几个视频&#xff0c;做一下笔记。以后依…

【ARM Coresight Debug 系列 -- ARMv8/v9 Watchpoint 软件实现地址监控详细介绍】

请阅读【嵌入式开发学习必备专栏 】 文章目录 ARMv8/v9 Watchpoint exceptionsWatchpoint 配置信息读取Execution conditionsWatchpoint data address comparisonsSize of the data accessWatchpoint 软件配置流程Watchpoint Type 使用介绍WT, Bit [20]: Watchpoint TypeLBN, B…

字符串反转巧妙处理、拼接、空格的跳跃处理-151. 反转字符串中的单词

题目链接及描述 151. 反转字符串中的单词 - 力扣&#xff08;LeetCode&#xff09; 题目分析 今天又遇到了曾经做过的题目&#xff0c;对于这道题目&#xff0c;曾经做过几遍了&#xff0c;即使之前做过&#xff0c;今天又遇到这道题目时&#xff0c;对于边界的处理仍然不够完…

pikachu靶场(命令执行(RCE)通关教程)

第1关 exec "ping" 1.打开网站 看到一个ping的字样&#xff0c;想到这里应该是要写一个IP地址&#xff0c;这里用本地回环地址 可以看到返回了&#xff0c;根据返回的TTL值&#xff0c;猜想到这里应该是Windows 使用命令可以观看之前写的博客。 所以直接写入127.…