从Linux角度具体理解程序翻译过程-----预处理、编译、汇编、链接

前言:

在C语言中,我们知道程序从我们所写的代码到可执行执行的过程中经历了以下过程

1.预处理

2.编译

3.汇编

4.链接

 可以通过下图来理解

翻译过程

1.预处理

该过程主要进行以下操作:

(1)头文件的包含

(2)define定义符号的替换,删除定义的符号(也就是宏定义) 

(3)注释的删除

(4)条件编译的处理(#ifdef, #else, #endif)

2.编译

(1)把C语言代码转化为汇编代码

3.汇编

(1)把汇编代码替换为机器指令(也可以说是机器指令,目标代码),形成符号表

(2)语法分析,此法分析,符号汇总,语义分析

4.链接

(1)合并段表

(2)符号表的合并和重定位

想知道程序的翻译环境和执行环境的详细过程,请移步:(暂未完成,敬请期待)

Linux下对其理解:

首先,我的codetest.c中的代码如下:

#include <stdio.h>

//宏定义
#define AC return
#define please 0

int main()
{
    printf("hello Linux\n");

    //注释部分
   // printf("hello Linux1\n");
   // printf("hello Linux2\n");
   // printf("hello Linux3\n");

    int* p = NULL;
    printf("%d\n", sizeof(p));

//条件编译语句
#ifdef MAX
    printf("MAX exist\n");
#else
    printf("MAX cannot find\n");
#endif

    //下面只是为了节目效果,请大家不要效仿,这是不好的编程习惯,我之前也从未这样子写过
    AC please;
}

1.预处理

从那篇文章我们知道了预处理之后,我们的test.c会变成test.i文件

{

拓展:

要注意,这是在windows环境下,在Linux环境下并不以后缀区分文件类型,而是通过:ll 指令,会显示如下信息:

文件类型文件权限硬链接数文件拥有者文件所属组文件大小(以字节为单位)文件创建时间或者最近更新使劲按文件名
-rw-rw-r-- 1

xkjtx

xkjtx  627Apr 18 21:32codetest
drwxr-xr-x 2xkjtxxkjtx    6Apr 13 19:42Desktop

Linux下文件信息:

在Linux中,输入ll命令会显示文件和目录的详细信息。这些信息通常分为若干列,每列的含义如下:

文件类型:

第1个字符代表文件类型:
-:普通文件
d:目录
l:软链接(符号链接)
c:字符设备文件
b:块设备文件
s:本地套接字
p:命名管道(FIFO)


接下来的九个字符分为三组,每组三个字符,代表文件权限:
r:可读权限
w:可写权限
x:可执行权限

每组分别代表文件拥有者(user)、所属组(group)和其他用户(other)的权限

硬链接数:

对于文件,这表示有多少个文件名指向该文件;对于目录,这表示该目录所含的子目录数(不包括.和..)。

文件拥有者:

显示文件的拥有者用户名。

文件所属组:

显示文件所属的用户组名称。

这个组存在的意义是:有时为了保护文件所属者的信息,文件只有自己可见,但这样子会有弊端:当文件所有者的同事或者上级想查看文件时,无法查看,只能打开other查看的权限,但是这样子所有人都可以看,而不只是上级和同事,因此设置了group(文件所属组)权限,设置了其他人可见,并保证了隐私

other:

不属于   文件拥有者   和   文件所属组   中的任何一者

}

因此当我们在Linux输入以下命令行:

其中:

-E:表示预处理

codetest.c:我们的代码所属文件

-o:理解为起别名

codetest.i:预处理后的文件名

gcc -E codetest.c -o codetest.i
//     代码文件名   预处理后的文件名

在输入:ls后会发现列表中多了一个文件:codetest.i

我们再使用以下命令:

vim codetest.c

进入codetest.c文件,再输入

:vs codetest.i

使其分屏操作,我们平时也可以用这种方式对比两个源文件的不同之处(写题的人都懂这种操作有多么重要吧)

以下左半部分为codetest.i,右半部分为codetest.c

图一:注意左侧高亮部分,这是我们在codetest.c文件中对stdio.h的包含在预处理好的文件中的展示,其实codetest.i中前800多行都是包含了stdio.h文件里的内容,这也就是我们所说的预处理第一个步骤:头文件的包含

 图二:

可以发现注释部分在codetest.i中消失了

条件编译中,因为MAX我们没有在宏定义中定义,因此它不执行:printf("MAX exist\n");

而是执行: printf("MAX cannot find\n");

而codetest.c中的AC please被替换为return 0;

这里也就解释了 :

1.预处理

该过程主要进行以下操作:

(1)头文件的包含{codetest.i中前800多行都是包含了stdio.h文件里的内容}

(2)define定义符号的替换,删除定义的符号(也就是宏定义) 

(3)注释的删除{注释部分在codetest.i中消失了;}

(4)条件编译的处理(#ifdef, #else, #endif)

{执行: printf("MAX cannot find\n");}

2.编译

从那篇文章我们知道了编译之后,我们的test.i会变成test.s文件

接下来,我们在Linux的命令行中输入:

gcc -S codetest.i -o codetest.s
//代码文件名(写成codetest.c也行,只是要再次预处理)   编译后的文件名

其中:

-S:表示编译

codetest.i:我们的代码所属文件(写成codetest.c也行,只是要再次预处理)

-o:理解为起别名

codetest.s:生成的编译后的文件名

再次输入:ls,就会发现多了个codetest.s文件 

使用以下命令:

vim codetest.s

就会出现以下样子

包括了movl这样的注记符,还有操作数,寄存器相关信息

这就是汇编代码,这也解释了:

2.编译

(1)把C语言代码转化为汇编代码

3.汇编

从那篇文章我们知道了汇编之后,我们的codetest.s会变成codetest.o文件

接下来,我们在Linux的命令行中输入:

gcc -c codetest.s -o codetest.o
//代码文件名(写成codetest.c,codetest.i,codetest.s也行,只是要再次进行之前的操作)   编译后的文件名

其中:

-c:表示编译(注意是小写)

codetest.s:我们的代码所属文件

-o:理解为起别名

codetest.o:编译后的文件名

再次输入:ls,就会发现多了个codetest.o文件 

再次进行以下操作:

使用以下命令:

vim codetest.o

就会出现以下样子 

这就是二进制,这也解释了:

3.汇编

(1)把汇编代码替换为机器指令(就是2进制指令)

4.链接

这一步不用像之前一样写-E,-S,-c这样子的命令,因为gcc自带了链接功能,直接输入以下代码就好:

gcc codetest.o -o codetest
// 代码文件名      生成的可执行文件名

输入ls,会发现多了个绿色的codetest文件

再次输入

./codetest

 执行codetest.c代码,输出以下部分

以上就是通过Linux查看C语言翻译环境的所有过程啦~~(预处理,编译,汇编,链接)

以下是识记小部分,

 * 你是不是被什么-E,-S,-c指令搞蒙了?去掉-看看,是不是就算ESc啊?键盘左上角的键哦  *

 * 是不是被.i  .s   .o 搞懵了?如果你装的是虚拟机,你就会发现iso就是你装在虚拟机上的镜像文件的后缀名哦,注意,这不是ios操作系统的ios,是iso,不要搞错了 ~~~  *

完结撒花~~哦吼吼~~

喜欢的给俺点点赞哦~

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

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

相关文章

怎样实现opc采集数据后传给web后端

现在很多老工厂要进行数字化改造&#xff0c;现场生产的各种数据需要传到web后端&#xff0c;很多工厂现场原有的自动监控系统已经采集了现场的各种数据&#xff0c;只是没有形成联网。如果前端自动化系统全部废除&#xff0c;重新做数字化控制系统&#xff0c;成本投入太大&am…

docker服务无法启动

背景&#xff1a;断电重启经常会导致磁盘io错误&#xff0c;甚至出现磁盘坏块 这时可以使用xfs_repair来修复磁盘&#xff0c;但是修复过程可能会导致部分数据丢失 xfs_repair -f -L /dev/sdc问题一&#xff1a; Apr 15 19:27:15 Centos7.6 systemd[1]: Unit docker.service e…

Java入门(JDK安装)

安装 JDK 下载 Java Downloads | Oracle 安装 下一步直接安装安装过程中&#xff0c;需要确定自己的安装位置 参考&#xff1a;D:\Java\jdk1.8.0_281_x64 演示位置 校验 终端输入 java -version 配置 1&#xff09;删除默认 javapath 默认情况下&#xff0c;可以在cm…

【C++题解】1607. 两位数运算

问题&#xff1a;1607. 两位数运算 类型&#xff1a;基本运算、拆位求解 题目描述&#xff1a; 小丽在编程课上学会了拆位运算&#xff0c;她已经可以拆出一个两位整数的十位和个位了&#xff0c;她想知道这个整数的十位 / 个位的结果是多少&#xff0c;请编程帮她实现&#…

VulnHub靶机 DC-5 打靶 渗透测试详情过程

VulnHub靶机 DC-5 打靶 详细渗透测试过程 目录 VulnHub靶机 DC-5 打靶 详细渗透测试过程一、将靶机导入到虚拟机当中二、渗透流程主机发现端口扫描目录爆破文件包含getshell反弹shell提权 一、将靶机导入到虚拟机当中 靶机地址&#xff1a; https://download.vulnhub.com/dc/…

【论文阅读】YOLO-World | 开集目标检测

Date&#xff1a;2024.02.22&#xff0c;Tencent AI Lab&#xff0c;华中科技大学Paper&#xff1a;https://arxiv.org/pdf/2401.17270.pdfGithub&#xff1a;https://github.com/AILab-CVC/YOLO-World 论文解决的问题&#xff1a; 通过视觉语言建模和大规模数据集上的预训练来…

HTTP/HTTPS详解

HTTP/HTTPS详解 1. HTTP1.1 HTTP基础知识1.2 HTTP建立和断开连接 2. HTTPS 1. HTTP 1.1 HTTP基础知识 HTTP是互联网上应用最为广泛的一种网络协议&#xff0c;是一个客户端和服务器端请求和应答的标准&#xff08;TCP&#xff09;&#xff0c;用 于从WWW服务器传输超文本到本…

学习一下选择排序,快速排序

1.选择排序 我们可以根据这动图看到&#xff0c;就是在这个数组里面我们选出最小的放进第一个位置&#xff0c;然后再选除了第一个位置最小的&#xff0c;剩下的数里面最小的放到第二个位置&#xff0c;是不是非常简单呢。 void SelectSort2(int* arr, int n) {int begin 0;…

Stable Diffusion 3 API 发布!超越Midjourney v6和DALL-E 3

Stable Diffusion 3 于 2 月首次宣布作为预览版发布。而今天&#xff0c;StabilityAI 正式推出了 Stable Diffusion 3 和 Stable Diffusion 3 Turbo API 的API接口服务。 Stability AI 称仍在持续改进该模型&#xff0c;并没有说明发布日期。模型还没发布&#xff0c;但API先来…

安装importlib_resources库的方法最终解答!_Python库

安装Python库importlib_resources 我的环境&#xff1a;Window10&#xff0c;Python3.7&#xff0c;Anaconda3&#xff0c;Pycharm2023.1.3 importlib_resources importlib_resources是一个用于访问Python包中非代码资源&#xff08;如文本、图片等&#xff09;的库&#xff…

neo4j使用详解(终章、neo4j的java driver使用模板及工具类——<可用于生产>)

Neo4j系列导航: neo4j安装及简单实践 cypher语法基础 cypher插入语法 cypher插入语法 cypher查询语法 cypher通用语法 cypher函数语法 neo4j索引及调优 neo4j java Driver等更多 1. 简介 本文主要是java使用neo4j driver操作neo4j的模板项目及非常有用的工具类,主要包括: 图…

yolov7模型输出层预测方法解读

本文从代码的角度分析模型训练阶段输出层的预测包括以下几个方面&#xff1a; 标注数据&#xff08;下文统称targets&#xff09;的正样本分配策略&#xff0c;代码实现位于find_3_positive。候选框的生成&#xff0c;会介绍输出层的预测值、GT、grid、 anchor之间的联系损失函…

【原创】springboot+mysql疫苗预约管理系统设计与实现

个人主页&#xff1a;程序猿小小杨 个人简介&#xff1a;从事开发多年&#xff0c;Java、Php、Python、前端开发均有涉猎 博客内容&#xff1a;Java项目实战、项目演示、技术分享 文末有作者名片&#xff0c;希望和大家一起共同进步&#xff0c;你只管努力&#xff0c;剩下的交…

《Kubernetes部署篇:基于Kylin V10+ARM架构CPU+外部etcd使用containerd部署K8S 1.26.15容器版集群(多主多从)》

总结&#xff1a;整理不易&#xff0c;如果对你有帮助&#xff0c;可否点赞关注一下&#xff1f; 更多详细内容请参考&#xff1a;企业级K8s集群运维实战 1、在当前实验环境中安装K8S1.25.14版本&#xff0c;出现了一个问题&#xff0c;就是在pod中访问百度网站&#xff0c;大…

ollama大语言模型

查看已经安装的大语言模型 ollama list运行大语言模型 ollama run llama2:latest

【EI会议征稿通知】2024年图像处理、机器学习与模式识别国际学术会议(IPMLP 2024)

2024年图像处理、机器学习与模式识别国际学术会议&#xff08;IPMLP 2024) 2024 International Conference on Image Processing, Machine Learning and Pattern Recognition 重要信息 大会官网&#xff1a;www.ipmlp.net&#xff08;点击参会/投稿/了解会议详情&#xff09;…

Elasticsearch:简化 KNN 搜索

作者&#xff1a;来自 Elastic Panagiotis Bailis 在这篇博客文章中&#xff0c;我们将深入探讨我们为了使 KNN 搜索的入门体验变得更加简单而做出的努力&#xff01; 向量搜索 向量搜索通过在 Elasticsearch 中引入一种新的专有的 KNN 搜索类型&#xff0c;已经可以使用一段…

蓝桥杯2024年第十五届省赛真题-数字接龙

思路&#xff1a;DFS&#xff0c;因为输入的i&#xff0c;j的顺序导致&#xff0c;方向向量中x是行编号&#xff0c;y是列编号。方向向量可能和直觉上不同。 错的 //int dx[8]{0,1,1,1,0,-1,-1,-1}; //int dy[8]{1,1,0,-1,-1,-1,0,1}; 对的 int dx[]{-1,-1,0,1,1,1,0,-1}; int…

论文复现《SplaTAM: Splat, Track Map 3D Gaussians for Dense RGB-D SLAM》

前言 SplaTAM算法是首个开源的基于RGB-D数据&#xff0c;生成高质量密集3D重建的SLAM技术。 通过结合3DGS技术和SLAM框架&#xff0c;在保持高效性的同时&#xff0c;提供精确的相机定位和场景重建。 代码仓库&#xff1a;spla-tam/SplaTAM: SplaTAM: Splat, Track & Map 3…

算法一:数字 - 两数之和

给定一个整数数组 nums 和一个目标值 target&#xff0c;请你在该数组中找出和为目标值的那 两个 整数&#xff0c;并返回他们的数组下标。 你可以假设每种输入只会对应一个答案。但是&#xff0c;数组中同一个元素不能使用两遍。 来源&#xff1a;力扣(LeetCode) 链接&#xf…