Linux下生成可执行程序的每一步过程以及链接库的初步认识

news2024/9/24 11:33:07

程序的翻译

程序在形成可执行程序之前都经历过一系列十分复杂的过程,也就是我们程序的翻译,程序的翻译经过以下阶段:

  1.  预处理(进行宏替换)
  2.  编译(生成汇编)
  3.  汇编(生成机器可识别代码)
  4.  连接(生成可执行文件或库文件)

就以C语言代码为例,当我们写好了一份C语言代码,第一部要进行头文件的包含,然后在主函数下咔咔一顿写,再开始翻译,也就是形成可执行程序的过程.

我们要了解翻译过程,大致是要将我们写的代码转换成汇编,然后将汇编形成二进制码,也就是计算机可以识别的代码,最后将目标二进制文件和链接库通过链接器连接生成可执行程序。

 预处理阶段

预处理执行的就是:1.将文件的头文件展开 2.宏替换 3.条件编译 4.代码注释的删除

而头文件展开是干啥呢,这里就要大略的谈谈头文件和库文件了,头文件就是我们的stdio.h,而我们包含的这个头文件功能起到一些函数、变量类型定义的作用,而函数的具体实现是在库文件里的,例如我们的printf函数也是需要实现的,就是在stdio.h定义的,如果我们要使用函数的话,编译器就需要到特定的库文件中去寻找该函数的实现,而库文件的内容实质上都是一些二进制。所以回到问题,头文件展开的实质就是将stdio.h里面的内容拷贝一份放在咱们的代码里。

宏替换就比较简单,就是将#define定义的宏变量,宏函数等内容进行替换。

条件编译就是将#if #else #endif等内容的执行

代码注释删除就不解释了哈

linux下我们编译C语言代码时可以用gcc编译器,编写C++代码时可以用g++编译器,而且这些编译器还可以执行到具体某个过程终止:例如想让代码就执行完预处理过程就终止的话可以 gcc -E test.c -o test.i //其实-E是指预处理过程,而-o是预处理的文件存放在test.i的文件中

test.c代码

 预处理之后:

其实并不仅仅只有这些,还有头文件展开的内容,由于内容过于丰富所以就未截取。 

编译

在这个阶段中,gcc 首先要检查代码的规范性、是否有语法错误等,以确定代码的实际要做的工作,在检查无误后,gcc 把代码翻译成汇编语言。

  • 编译过程为 扫描程序-->语法分析-->语义分析-->源代码优化-->代码生成器-->目标代码优化;
  • 扫描程序进行词法分析,从左向右,从上往下扫描源程序字符,识别出各个单词,确定单词类型
  • 语法分析是根据语法规则,将输入的语句构建出分析树parse tree或者语法树syntax tree
  • 语义分析是根据上下文分析函数返回值类型是否对应这种语义检测,可以理解语法分析就是描述一个句子主宾谓是否符合规则,而语义用于检测句子的意思是否是正确的
  • 目标代码优化就是执行死代码删除、函数内联、for循环的循环控制变量调度到寄存器访问、强度削弱...(而死代码的删除并不是注释删除而是移除根本执行不到的代码,或者对程序运行结果没有影响的代码    内联函数,也叫编译时期展开函数, 指的是建议编译器将内联函数体插入并取代每一处调用函数的地方,从而节省函数调用带来的成本,使用方式类似于宏,但是与宏不同的是内联函数拥有参数类型的校验,以及调试信息,而宏只是文本替换而已    for循环的循环控制变量,通常被cpu访问频繁,因此如果调度到寄存器中进行访问则不用每次从内存中取出数据,可以提高访问效率     强度削弱是指执行时间较短的指令等价的替代执行时间较长的指令,比如 num % 128 与 num & 127 相较,则明显&127更加轻量)

上面这块内容为摘抄大佬文案,我也不太懂,看看猪肉就行了。

而这一过程的指令就是:gcc -S test.i -o test.s//这里其实-S后面跟test.c也行,只不过我们刚刚已经执行了预处理过程,紧接着就是编译,所以直接对test.i操作即可。

这其实就是编译的过程:形成汇编代码。

汇编

汇编就是将编译阶段形成的汇编代码转换成二进制文件,此时就可以被计算机识别。

而这一过程的指令就是:gcc -c test.s -o test.o//这里其实-c后面跟test.c也行,只不过我们刚刚已经执行了编译过程,紧接着就是汇编,所以直接对test.i操作即可。

这里是部分截图,而且需要查看该二进制码的指令是od,如果一般的查看方式的话是一堆乱码。

链接

链接就是将目标文件(test.o)与链接库通过链接器链接起来的过程。

而这里主要就是了解一下什么是链接库。链接库也划分成静态库和动态库两种。

链接库

在我们实现C语言程序的时候,一般是要在开头包含头文件的,而对于头文件的作用就是声明一些你用到的函数,就像printf函数,但是函数的定义(实现)在哪里呢,其实就是在库文件(libc.so.6
)中,而在使用的过程中系统会默认到该路径下去寻找,这样就有函数的定义的,也就可以正常使用了。

静态库

静态库是指编译链接时,把库文件的代码全部加入到可执行文件中,因此生成的文件比较大,但在运行时也就不再需要库文件了。其后缀名一般为“.a”

就是静态库进入.o的二进制目标文件中,链接成可执行程序的时候,链接器会复制静态库内的函数和数据进入可执行程序中
 

动态库

动态库与之相反,在编译链接时并没有把库文件的代码加入到可执行文件中,而是在程序执行时由运行时链接文件加载库,这样可以节省系统的开销。动态库一般后缀名为“.so”,如前面所述的 libc.so.6 就是动态库。gcc 在编译时默认使用动态库。完成了链接之后,gcc 就可以生成可执行文件。

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

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

相关文章

嵌入式C 语言中的三块技术难点

​ C 语言在嵌入式学习中是必备的知识,甚至大部分操作系统都要围绕 C 语言进行,而其中有三块技术难点,几乎是公认级别的“难啃的硬骨头”。 今天就来带你将这三块硬骨头细细拆解开来,一定让你看明白了。 0x01 指针 指针是公认…

Python 人工智能编程指南:基础、库和工具大全解析

Python 已成为人工智能 (AI) 和机器学习领域的通用语言。其广泛的应用、强大的库生态系统和用户友好的语法使其成为人工智能爱好者、数据科学家和研究人员的理想选择。在这份综合指南中,我们将探讨用于 AI 编程的 Python 基础知识,深入研究关键库&#x…

CKA真题分析-2023年度

补充信息 #补全 # apt install bash-completion source <(kubectl completion bash)# kubectl config get-contexts # cat ~/.kube/config |grep current# kubectl config current-context kubectl config use-context复制粘贴 ctrlshiftc ctrlshiftv # edit编辑时只能使…

ashx后台获取GET、POST、JSON方式提交的刷卡信息,并回应驱动读卡器显示文字播报语音

本示例使用设备&#xff1a; RFID网络WIFI无线TCP/UDP/HTTP可编程二次开发读卡器POE供电语音-淘宝网 (taobao.com) <% WebHandler Language"C#" Class"HttpReader" %>using System; using System.Web; using System.IO; using Newtonsoft.Json;publ…

Ubuntu 22.04.3 LTS安装

最近换电脑了&#xff0c;准备重新装一下ubuntu。多年前装过ubuntu很老的版本&#xff0c;现在发现官网最新的LTS版本是 Ubuntu 22.04.3 LTS 版本。那重新装的话&#xff0c;肯定装最新的版本了。这里我记录下自己的安装过程&#xff0c;作为以后的笔记查看。 我的环境&#x…

《C++ primer plus》精炼(OOP部分)——对象和类(4)

“学习是人类进步的阶梯&#xff0c;也是个人成功的基石。” - 罗伯特肯尼迪 文章目录 友元函数利用友元函数重载<<运算符重载部分示例&#xff1a;矢量类 友元函数 先看看在上一章中我们作为例子的代码&#xff1a; class Student{string name;int grade;int operator…

【开发工具】idea 的全局搜索快捷键(Ctrl+shift+F)失效

文章目录 前言1. 取消 输入法的快捷键&#xff08;推荐使用&#xff09;2.更改 idea的快捷键3. 热键占用总结 前言 当你发现在idea 中看到用于全局搜索的快捷键就是 CtrlshiftF&#xff0c;可是怎么按都不管用的时候&#xff0c;你就不要再执着于自己的操作继续狂点电脑按键了…

SAP 自定义搜索帮助创建与使用

如何创建自定义的搜索帮助 1. 进入事务码SE11,自定义一个搜索帮助的名字 2. 维护数据收集的选择方法以及对话行为和参数信息 点击激活&#xff0c;至此&#xff0c;搜索帮助创建完成 3. 可以给数据表中的对应字段添加搜索帮助 SE11进入&#xff0c;输入数据表名&#xff0c;…

PHP 如何创建一个 composer 包 并在 项目中使用自己的 composer sdk 包

第一步创建一个composer SDK项目 创建一个 composer.json文件或使用 命令 &#xff08;如果不清楚怎么弄 直接跳过即可&#xff0c;一般都会默认配置&#xff09; composer init这是生成的composer.json文件 将自己要使用的包添加到 require 中&#xff0c;如果没有require则…

【计算机视觉 | CNN】Image Model Blocks的常见算法介绍合集(四)

文章目录 一、Dilated Bottleneck with Projection Block二、NVAE Generative Residual Cell三、NVAE Encoder Residual Cell四、Bottleneck Transformer Block五、Spatial Feature Transform六、Big-Little Module七、Scale Aggregation Block八、Multiscale Dilated Convolut…

Zookeeper 启动失败【Cannot open channel to 3 at election address...】

文章目录 完整报错信息解决方法1.检查文件夹权限2.未监听所有IP3.IP映射名称与 ID 不对应 完整报错信息 Cannot open channel to 3 at election address hadoop121/192.168.10.121:3888 java.net.ConnectException 解决方法 1.检查文件夹权限 检查当前用户是否拥有 Zookeep…

基于SpringBoot的点餐系统

基于SpringBootVue的点餐系统、食堂餐厅点餐系统、前后端分离 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringBoot、Vue、Mybaits Plus、ELementUI工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 【主要功能】 角色&#xff1a;管理员、用户 管理员…

創能Tronenergy:全球首創,TRON能量算力增值平台

全球知名的TRON能量交易平台Tronenergy再次突破&#xff0c;推出了令人振奮的重磅功能&#xff01;作為全球首創的USDT轉賬0手續費平台&#xff0c;Tronenergy為用戶帶來了一場USDT轉賬革命&#xff0c;立即體驗Tronenergy&#xff0c;享受便捷、經濟的轉賬服務&#xff0c;同時…

Leetcode162. 寻找峰值

力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 峰值元素是指其值严格大于左右相邻值的元素。 给你一个整数数组 nums&#xff0c;找到峰值元素并返回其索引。数组可能包含多个峰值&#xff0c;在这种情况下&#xff0c;返回 任何一个峰值 所在位置即…

CSRF和SSRF有什么不同?

文章目录 CSRF复现SSRF复现启动环境漏洞复现探测存活IP和端口服务计划任务反弹shell 区别 CSRF复现 打开dvwa&#xff0c;将难度调为low&#xff0c;点击CSRF&#xff0c;打开后发现有一个修改密码的输入框&#xff1a; 在这里修改密码&#xff0c;并用bp抓包&#xff0c;在…

eNSP网络学习

一、eNSP 1.什么是eNSP eNSP(Enterprise Network Simulation Platform)是一款由华为提供的免费的、可扩展的、图形化操作的网络仿真工具平台&#xff0c;主要对企业网络路由器、交换机进行软件仿真&#xff0c;完美呈现真实设备实景&#xff0c;支持大型网络模拟&#xff0c;让…

指针进阶笔试题

今天分享的是指针的笔试题&#xff0c;相信看完这篇文章对指针又会有深入的了解&#xff0c;让我们来学习吧。 首先分享的是指针和数组的关系&#xff0c;我们都知道数组名是首元素的地址&#xff0c;那就让我们来看一下一维数组和指针的关系吧 //一维数组 int a[] { 1,2,3,4…

go-GC垃圾回收

GC GC是自动化内存管理回收机制 虚拟内存函数栈的数据是会根据函数返回而自动销毁的&#xff0c;而堆上的数据是不会随着函数自动销毁的&#xff0c;堆内数据会随着程序运行而逐渐变大&#xff0c;从而导致内存OOM&#xff0c;Go语言就用了GC来清理堆上的内存数据。 如何区分…

leetcode 2602. 使数组元素全部相等的最少操作次数

给你一个正整数数组 nums 。 同时给你一个长度为 m 的整数数组 queries 。第 i 个查询中&#xff0c;你需要将 nums 中所有元素变成 queries[i] 。你可以执行以下操作 任意 次&#xff1a; 将数组里一个元素 增大 或者 减小 1 。 请你返回一个长度为 m 的数组 answer &#xf…

KCC@大连 | 一场关于开源商业的私享脑暴会

KCC&#xff0c;全称 KAIYUANSHE City Community&#xff08;中文&#xff1a;开源社城市社区&#xff09;是由开源社发起&#xff0c;旨在让开源社区在每个城市落地生根的地域性开源组织。 自2023年2月份发起以来&#xff0c;我们已经在南京、上海、深圳、北京、硅谷、新加坡、…