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

目录

前言:

翻译过程

1.预处理

2.编译

3.汇编

4.链接

Linux下对其理解:

1.预处理

拓展:

Linux下文件信息:

文件类型:

硬链接数:

文件拥有者:

文件所属组:

other:

2.编译

3.汇编

4.链接


前言:

在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 0int 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 MAXprintf("MAX exist\n");
#elseprintf("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.mzph.cn/diannao/3250.shtml

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

相关文章

区块链安全应用-------压力测试

基于已有的链进行测试&#xff08;build_chain默认建的链 四个节 点&#xff09;&#xff1a; 第一步&#xff1a;搭链 1. 安装依赖 在ubuntu操作系统中&#xff0c;操作步骤如下&#xff1a; sudo apt install -y openssl curl 2. 创建操作目录, 下载安装脚本 ## 创建操作…

3个比较不错的Linux云音乐应用程序整理

在现代音乐流媒体时代&#xff0c;基于云的音乐应用程序因其便利性和可访问性而变得非常流行。Linux 用户尤其寻求可靠且功能丰富的音乐播放器来无缝地享受他们喜爱的音乐。 在这里&#xff0c;我们探讨了三个最好的基于云的音乐应用程序&#xff0c;每个应用程序都提供专为 L…

Java Web 网页设计(1)

不要让追求之舟停泊在幻想的港湾 而应扬起奋斗的风帆 驶向现实生活的大海 网页设计 1.首先 添加框架支持 找到目录右键添加 找到Web Application选中 点击OK 然后 编辑设置 找到Tomcat--local 选中 点击OK 名称可以自己设置 找到对应文件夹路径 把Tomcat添加到项目里面 因为…

【Hadoop】-HDFS的Shell操作[3]

目录 前言 一、HDFS集群启停命令 1.一键启停脚本可用 2.独立进程启停可用 二、文件系统操作命令 1、创建文件夹 2、查看指定目录下内容 3、上传文件到HDFS指定目录下 4、查看HDFS文件内容 5、下载HDFS文件 6、拷贝HDFS文件 7、追加数据到HDFS文件中 8、HDFS数据移…

哪吒汽车把最后的翻身筹码,全压在了这辆新车上

正如比亚迪王传福所说&#xff0c;新能源车市场已进入惨烈淘汰赛环节。 近几年国内新能源车销量增长势头迅猛&#xff0c;仅过去的 2023 年产销便分别达 958.7 万辆和 949.5 万辆&#xff0c;同比增长 35.8% 和 37.9%。 销量高速增长背后自然也带来了越来越激烈的竞争。 过去…

Footprint Analytics 与 GalaChain 达成战略合作

​ Footprint Analytics 宣布与 GalaChain 达成战略合作。GalaChain 是 Gala 旗下的 Layer 1 区块链。此次合作标志着双方在游戏&#xff08;包括 Gala Games) 、娱乐和金融等多个行业的区块链生态系统革新方面迈出了重要的一步。 GalaChain 致力于满足企业级项目的广泛需求&…

算法-栈操作

1047. 删除字符串中的所有相邻重复项 - 力扣&#xff08;LeetCode&#xff09; class Solution { public:string removeDuplicates(string s) {string stack;for(char& ch:s){if(stack.size()>0&&chstack.back()){stack.pop_back();}else{stack.push_back(ch);}…

AI大模型实现软件智能化落地实践

1、什么是大模型 大型语言模型&#xff08;Large Language Model&#xff0c;LLM&#xff1b;Large Language Models&#xff0c;LLMs)。 大语言模型是一种深度学习模型&#xff0c;特别是属于自然语言处理&#xff08;NLP&#xff09;的领域&#xff0c;一般是指包含数干亿&…

Pandas 模块-操纵数据(11)-二元运算--超级add、sub、mul、div、mod、pow等等

目录 1. DataFrame.add 1.1 DataFrame.add 语法结构 1.2 DataFrame.add 参数说明 1.3 DataFrame.add 用法示例 1.3.1 正常的使用 1.3.2 需要注意类型相符合 2. DataFrame.sub 2.1 DataFrame.sub 语法结构 2.2 DataFrame.sub 参数说明 2.3 DataFrame.sub 用法示例 3.…

传媒论坛编辑部传媒论坛杂志社传媒论坛杂志2024年第7期目录

专题│场景传播研究 场景传播&#xff1a;一场遮盖自我与寻找自我的博弈 胡沈明; 3 基于CiteSpace的中国场景传播研究热点分析 管倩;粟银慧; 4-610《传媒论坛》投稿&#xff1a;cnqikantg126.com 数字世界的美与危&#xff1a;场景传播的失范与应对之举 王依晗;章洁…

分布式-知识体系

分布式系统 本质就是一堆机器的协同&#xff0c;要做的就是用各种手段来让机器的运行达到预期 分布式业务场景 分布式四纵四横说 基于 MSA&#xff08;微服务架构&#xff09;的分布式知识体系 相关概念 – 【摘自网络原文】 节点与网络 节点 传统的节点也就是一台单体的物…

MySQL数据类型:字符串类型详解

MySQL数据类型&#xff1a;字符串类型详解 在MySQL数据库中&#xff0c;字符串数据类型用于存储各种文本信息。这些数据类型主要包括CHAR、VARCHAR、TEXT和BLOB等。 CHAR与VARCHAR CHAR CHAR类型用于存储固定长度的字符串。它的长度在创建表时就已确定&#xff0c;长度范围…

QJ71C24N-R2 三菱Q系列串行通信模块

三菱Q系列串行通信模块是通过串行通信用的RS-232、RS-422/485线路将对方设备与Q系列可编程控制器CPU相连接,以实现如下所示的数据通信的模块。通过使用调制解调器/终端适配器,可以利用公共线路(模拟/数字)实现与远程设备间的数据通信。 QJ71C24N-R2参数说明&#xff1a;串行RS-…

为什么36KbRAM会配置为32K×1,少的那4Kb去哪了?

首先我们需要了解BRAM的相关知识&#xff0c;可以参考下面两篇文章&#xff1a; Xinlinx FPGA内的存储器BRAM全解-CSDN博客 为何有时简单双口RAM是真双口RAM资源的一半-CSDN博客 本问题的背景是&#xff1a; 每个36Kb块RAM也可以配置成深度宽度为64K 1(当与相邻的36KB块RA…

淘宝新店没有流量和访客怎么办

淘宝新店没有流量和访客时&#xff0c;可以采取以下措施来提升店铺的流量和吸引更多的访客&#xff1a; 3an推客是给商家提供的营销工具&#xff0c;3an推客CPS推广模式由商家自主设置佣金比例&#xff0c;以及设置商品优惠券&#xff0c;激励推广者去帮助商家推广商品链接&…

SVG 绘制微信订阅号icon

效果 代码 <!DOCTYPE html> <html> <body><svg xmlns"http://www.w3.org/2000/svg" version"1.1" width"600" height"600"><rect x"0" y"0" rx"0" ry"0" width&…

JavaEE 初阶篇-深入了解 UDP 通信与 TCP 通信(综合案例:实现 TCP 通信群聊)

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 UDP 通信 1.1 DatagramSocket 类 1.2 DatagramPacket 类 1.3 实现 UDP 通信&#xff08;一发一收&#xff09; 1.3.1 客户端的开发 1.3.2 服务端的开发 1.4 实现 …

Arm功耗管理精讲与实战

安全之安全(security)博客目录导读 思考 1、为什么要功耗管理&#xff1f;SOC架构中功耗管理示例&#xff1f;功耗管理挑战&#xff1f; 2、从单核->多核->big.LITTLE->DynamIQ&#xff0c;功耗管理架构演进? 3、什么是电压域&#xff1f;什么是电源域&#xff1f…

C++高级特性:异常概念与处理机制(十四)

1、异常的基本概念 异常&#xff1a;是指在程序运行的过程中发生的一些异常事件&#xff08;如&#xff1a;除数为0&#xff0c;数组下标越界&#xff0c;栈溢出&#xff0c;访问非法内存等&#xff09; C的异常机制相比C语言的异常处理&#xff1a; 函数的返回值可以忽略&…

《系统架构设计师教程(第2版)》第10章-软件架构的演化和维护-01-软件架构演化概述

文章目录 1. 演化的重要性2. 架构演化示例 教材中&#xff0c;本节名为&#xff1a;“软件架构演化和定义的关系” 1. 演化的重要性 演化目的&#xff1a;维持软件架构自身的有用性 为什么说&#xff0c;软件架构是演化来的&#xff0c;而不是设计来的&#xff1f; 软件架构的…