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

news2024/9/24 11:25:57

前言:

在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,不要搞错了 ~~~  *

完结撒花~~哦吼吼~~

喜欢的给俺点点赞哦~

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

稀碎从零算法笔记Day52-LeetCode:从双倍数组中还原原数组

题型&#xff1a;数组、贪心 链接&#xff1a;2007. 从双倍数组中还原原数组 - 力扣&#xff08;LeetCode&#xff09; 来源&#xff1a;LeetCode 题目描述 一个整数数组 original 可以转变成一个 双倍 数组 changed &#xff0c;转变方式为将 original 中每个元素 值乘以 …

EFK架构部署

7.17版本 准备工作 配置域名 cat >> /etc/hosts <<EOF 192.168.199.149 elk149daidaiedu.com 192.168.199.150 elk150daidaiedu.com 192.168.199.155 elk155daidaiedu.com EOF 修改主机名 hostnamectl set-hostname elk155.daidaiedu.com 免密登录 ssh-keyge…

# 从浅入深 学习 SpringCloud 微服务架构(一)基础知识

从浅入深 学习 SpringCloud 微服务架构&#xff08;一&#xff09;基础知识 1、系统架构演变&#xff1a; 1&#xff09;单体应用架构。如电商项目。 用户管理、商品管理、订单管理&#xff0c;在一个模块里。 优点&#xff1a;开发简单&#xff0c;快速&#xff0c;适用于…

VScode远程连接虚拟机提示: 无法建立连接:XHR failed.问题解决方案

一问题描述 在vscode下载插件Remote-SSH远程连接虚拟机时提示无法建立连接 二.最大嫌疑原因&#xff1a; 我也是在网上找了许久&#xff0c;发现就是网络原因&#xff0c;具体不知&#xff0c;明明访问别的网页没问题&#xff0c;就是连不上&#xff0c;然后发现下载vscode的…

前端CSS基础4(像素,颜色,字体属性大小复合属性)

前端CSS基础4&#xff08;像素&#xff0c;颜色&#xff0c;字体属性大小复合属性&#xff09; CSS代码编写位置CSS像素CSS颜色CSS常用字体属性和大小字体的复合属性 CSS代码编写位置 在HTML文件的头部使用 <head><style>/* 在这里编写CSS代码 */</style> …

Meta Llama 3强势来袭:迄今最强开源大模型,性能媲美GPT-4

前言 Meta的最新语言模型Llama 3已经发布&#xff0c;标志着在大型语言模型&#xff08;LLM&#xff09;领域的一次重大突破&#xff0c;其性能在行业内与GPT-4相媲美。此次更新不仅提升了模型的处理能力和精确性&#xff0c;还将开源模型的性能推向了一个新的高度。 Huggingf…

从0开始学人工智能测试节选:Spark -- 结构化数据领域中测试人员的万金油技术(二)

Dataframe dataframe 是spark中参考pandas设计出的一套高级API&#xff0c;用户可以像操作pandas一样方便的操作结构化数据。毕竟纯的RDD操作是十分原始且麻烦的。而dataframe的出现可以让熟悉pandas的从业人员能用非常少的成本完成分布式的数据分析工作&#xff0c; 毕竟跟数据…

数仓建模—数仓架构发展史

数仓建模—数仓架构发展史 时代的变迁&#xff0c;生死的轮回&#xff0c;历史长河滔滔&#xff0c;没有什么是永恒的&#xff0c;只有变化才是不变的&#xff0c;技术亦是如此&#xff0c;当你选择互联网的那一刻&#xff0c;你就相当于乘坐了一个滚滚向前的时代列车&#xf…

电视音频中应用的音频放大器

电视机声音的产生原理是将电视信号转化为声音&#xff0c;然后通过扬声器将声音播放出来。当我们打开电视并选择频道时&#xff0c;电视机首先从天线或有线电视信号中获取声音信号。声音信号经过放大器放大之后&#xff0c;就能够通过扬声器发出声音。电视机声音的产生原理和音…

Ubuntu20.04 ISAAC SIM仿真下载使用流程(4.16笔记补充)

机器&#xff1a;华硕天选X2024 显卡&#xff1a;4060Ti ubuntu20.04 安装显卡驱动版本&#xff1a;525.85.05 参考&#xff1a; What Is Isaac Sim? — Omniverse IsaacSim latest documentationIsaac sim Cache 2023.2.3 did not work_isaac cache stopped-CSDN博客 Is…

2024蓝桥杯每日一题(最短路径)

备战2024年蓝桥杯 -- 每日一题 Python大学A组 试题一&#xff1a;奶牛回家 试题二&#xff1a;Dijkstra求最短路 II 试题三&#xff1a;spfa求最短路 试题四&#xff1a;作物杂交 试题一&#xff1a;奶牛回家 【题目描述】 晚餐时间马上就到了&#x…

【JavaEE多线程】Thread类及其常见方法(上)

系列文章目录 &#x1f308;座右铭&#x1f308;&#xff1a;人的一生这么长、你凭什么用短短的几年去衡量自己的一生&#xff01; &#x1f495;个人主页:清灵白羽 漾情天殇_计算机底层原理,深度解析C,自顶向下看Java-CSDN博客 ❤️相关文章❤️&#xff1a;清灵白羽 漾情天…

【opencv】dnn示例-segmentation.cpp 通过深度学习模型对图像进行实时语义分割

模型下载地址&#xff1a; http://dl.caffe.berkeleyvision.org/ 配置文件下载&#xff1a; https://github.com/opencv/opencv_extra/tree/4.x/testdata/dnn 该段代码是一个利用深度学习进行语义分割的OpenCV应用实例。下面将详细解释代码的功能和方法。 引入库 引入了一些必要…

蓝桥杯2024年第十五届省赛真题-宝石组合

思路&#xff1a;参考博客&#xff0c;对Ha,Hb,Hc分别进行质因数分解会发现&#xff0c;S其实就等于Ha&#xff0c;Hb&#xff0c;Hc的最大公约数&#xff0c;不严谨推导过程如下&#xff08;字丑勿喷&#xff09;&#xff1a; 找到此规律后&#xff0c;也不能枚举Ha&#xff…

Go 单元测试之mock接口测试

文章目录 一、gomock 工具介绍二、安装三、使用3.1 指定三个参数3.2 使用命令为接口生成 mock 实现3.3 使用make 命令封装处理mock 四、接口单元测试步骤三、小黄书Service层单元测试四、flags五、打桩&#xff08;stub&#xff09;参数 六、总结6.1 测试用例定义6.2 设计测试用…

医学图像三维重建与可视化系统 医学图像分割 区域增长

医学图像的三维重建与可视化&#xff0c;这是一个非常有趣且具有挑战性的课题&#xff01;在这样的项目中&#xff0c;可以探索不同的医学图像技术&#xff0c;比如MRI、CT扫描等&#xff0c;然后利用这些图像数据进行三维重建&#xff0c;并将其可视化以供医生或研究人员使用。…

解决Mac使用Vscode无法调用外部终端

前言 今天遇到一个很奇怪的问题&#xff0c;之前好好的用Vscode还能调用外部终端&#xff0c;怎么今天不行了&#xff1f;问题出在哪里呢&#xff1f;请听我娓娓道来。 检查配置文件 我查看了一下配置文件&#xff0c;发现配置文件都是调用外部控制台&#xff0c;没毛病啊。 …

Objective-C网络数据捕获:使用MWFeedParser库下载Stack Overflow示例

概述 Objective-C开发中&#xff0c;网络数据捕获是一项常见而关键的任务&#xff0c;特别是在处理像RSS源这样的实时网络数据流时。MWFeedParser库作为一个优秀的解析工具&#xff0c;提供了简洁而强大的解决方案。本文将深入介绍如何利用MWFeedParser库&#xff0c;以高效、…

(最详细)关于List和Set的区别与应用

关于List与Set的区别 List和Set都继承自Collection接口&#xff1b; List接口的实现类有三个&#xff1a;LinkedList、ArrayList、Vector。Set接口的实现类有两个&#xff1a;HashSet(底层由HashMap实现)、LinkedHashSet。 在List中&#xff0c;List.add()是基于数组的形式来添…

Spring Boot后端+Vue前端:打造高效二手车交易系统

作者介绍&#xff1a;✌️大厂全栈码农|毕设实战开发&#xff0c;专注于大学生项目实战开发、讲解和毕业答疑辅导。 &#x1f345;获取源码联系方式请查看文末&#x1f345; 推荐订阅精彩专栏 &#x1f447;&#x1f3fb; 避免错过下次更新 Springboot项目精选实战案例 更多项目…