C++编译链接原理

从底层剖析程序从编译到运行的整个过程

三个阶段

    • 一、编译阶段
    • 二、链接阶段
    • 三、运行阶段

为了方便解释,给出两端示例代码,下面围绕代码进行实验:

//sum.cpp
int gdata = 10;
int sum(int a,int b)
{return a+b;
}
//main.cpp
extern int gdata;
int sum(int ,int);static int stat;int data = 20;int main()
{int a = gdata;int b = data;int ret = sum(a,b);return 0;
}

前两个阶段:
在这里插入图片描述

一、编译阶段

在这里插入图片描述
三件重要的事情:
编译阶段只关注自己模块内的事情
编译阶段不分配虚拟空间地址,无法运行
目标文件由各个段组成

编译阶段的产物是可重定位的二进制目标文件,由各个段组成
在这里插入图片描述
一、符号表(.symtab段)
查看符号表命令:objdump -t main.o
在这里插入图片描述
1.符号表中存储程序产生的符号,如
静态全局变量stat的符号为_ZL4stat ,定义在.bss区域
全局变量data的符号为data,定义在.data区域
主函数main()的符号为main,定义在.text区域
外部变量gdata的符号为gdata,定义为UND,表示符号的引用,不知道在哪里定义
外部函数sum(int,int)的符号为_Z3sumii,定义为UND,表示符号的引用,不知道在哪里定义

2.符号表中可以看到变量的链接属性
l:表示lcoal,符号只能在当前文件可见,内部链接属性
g:表示global,符号可以在所有文件可见,外部链接属性

所以链接的时候链接器只能看见gloal的符号 看不到lcoal的符号
这就解释了静态全局变量/函数 和普通全局变量/函数同名的问题
在多个文件中可以定义名字相同的静态全局变量/函数,因为local属性链接器不可见,但若多个文件中普通的全局变量/函数重名,因为具有global属性,链接的时候符号解析就会冲突

3.编译过程中变量不分配虚拟空间地址
我们查看以下.text段,注意需要带有-g输出调试信息
g++ -c main.cpp -g
objdump -S main.o
在这里插入图片描述观察,编译阶段产生了二进制机器码,但是不分配虚拟空间地址,所以地址先用0替代,即编译阶段指令没法用,需要等链接阶段分配虚拟地址补上地址才有用,这就是目标文件无法运行的原因之一
4.查看目标文件的各个段
命令:readelf -S main.o
在这里插入图片描述

二、链接阶段

在这里插入图片描述

链接所有的编译完成的目标文件(.o)和静态库文件(.a)
链接步骤:
步骤一:
将所有的目标文件的各个段进行合并
main.o的.text段和sum.o的.text段合并
main.o的.data段和sum.o的.data段合并
main.o的.bss和sum.o的.bss段合并
合并后进行符号解析
如链接阶段符号为UND(符号引用)的,都需要找到该符号定义的地方,如果没有找到=符号未定义,找到多个定义=符号重定义
UND 找到定义解析成具体 .text .data ..

步骤二:
符号的重定位(重定向)
符号解析之后,给所有的符号分配虚拟地址空间,成为了可执行文件

验证
使用链接器自己链接::ld -e main sum.o main.o
查看符号表:objdump -t a.out
在这里插入图片描述
可以看到所有符号均有定义的段,无UND符号引用的情况
所有符号均分配了地址(看第一列)

再看看代码段.text
在这里插入图片描述
之前机器码缺少地址的,现在也都补充上了,所以变成了可以运行的二进制机器码(指令)

补充1:
看一下可执行文件的文件头信息
在这里插入图片描述

.text段的信息
在这里插入图片描述
可以发现,可执行文件头记录了程序入口指令地址,所以CPU知道从哪个指令开始执行(这里是main函数作为入口)

补充2:
可执行文件所有的段都和二进制目标文件相同,多了一个programa headers段,用来告诉操作系统,运行这个程序的时候,把哪些内容加载进内存(数据段 指令段),注意:不是所有的段都需要加载进内存的
查看programa headers段:readelf -l a.out
在这里插入图片描述

三、运行阶段

在这里插入图片描述

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

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

相关文章

Stream流的简单用法

filter //stream流中的filter //filter 方法用于通过设置的条件过滤出元素。以下代码片段使用 filter 方法过滤掉空字符串&#xff1a; List<String> filter Arrays.asList("mz", "", "mz55", "m", "MZ"); Stream&l…

初始redis:在Ubuntu上安装redis

1.先切换到root用户 使用su命令切换到root 2.使用apt命令来搜索redis相关的软件包 命令&#xff1a;apt search redis 3.下载redis 命令&#xff1a; apt install redis 在Ubuntu 20.04中 &#xff0c;下载的redis版本是redis5 4.查看redis状态 命令&#xff1a; netst…

Python自动化测试系列[v1.0.0][高效自动化设计]

Python多线程应用于自动化测试 将多线程在测试巧妙地应用&#xff0c;确实会带来很多好处&#xff0c;并且这是充分利用机器资源执行高效率测试很好的方式 # -*- coding: utf-8 -*- import threading from time import ctime import time from selenium import webdriverdef …

LLM 入门与实践(四) Yi 部署与分析

本文截取自20万字的《PyTorch实用教程》&#xff08;第二版&#xff09;&#xff0c;敬请关注&#xff1a;《Pytorch实用教程》&#xff08;第二版&#xff09;无论是零基础入门&#xff0c;还是CV、NLP、LLM项目应用&#xff0c;或是进阶工程化部署落地&#xff0c;在这里都有…

python对象

类 我们目前所学习的对象都是Python内置的对象但是内置对象并不能满足所有的需求&#xff0c;所以我们在开发中经常需要自定义一些对象类&#xff0c;简单理解它就相当于一个图纸。在程序中我们需要根据类来创建对象类就是对象的图纸&#xff01;我们也称对象是类的实例&#…

JAVA--IO流

一、IO流什么&#xff1f; I/O是Input/output的缩写&#xff0c;用于处理设备之间的数据传输。如读/写文件、网络通讯。 java程序中&#xff0c;对于数据的输入、输出是以流&#xff08;Stream)的方式进行。 Java.io包下提供了各种流类和接口&#xff0c;用以获取不同种类的数…

web自动化(六)unittest 测试报告跳过用例

三种类型测试报告&#xff1a;unittest.TextTestRunner、BeautifulReport、HTMLTestRunner Python3.0 无法直接安装 HTMLTestRunner 安装 XTestRunner pip install XTestRunner安装 BeautifulReport pip install BeautifulReportimport unittestclass TestSkipCase(unittest…

ELfK logstash filter模块常用的插件 和ELFK部署

ELK之filter模块常用插件 logstash filter模块常用的插件&#xff1a; filter&#xff1a;表示数据处理层&#xff0c;包括对数据进行格式化处理、数据类型转换、数据过滤等&#xff0c;支持正则表达式 grok 对若干个大文本字段进行再分割成一些小字段 (?<字段名…

【算法篇】KMP算法,一种高效的字符串匹配算法

我们今天了解一个字符串匹配算法-KMP算法&#xff0c;内容难度相对来说较高&#xff0c;建议先收藏再细品&#xff01;&#xff01;&#xff01; KMP算法的基本概念 KMP算法是一种高效的字符串匹配算法&#xff0c;由D.E.Knuth&#xff0c;J.H.Morris和V.R.Pratt提出的&#…

LLMs之gptpdf:gptpdf的简介、安装和使用方法、案例应用之详细攻略

LLMs之gptpdf&#xff1a;gptpdf的简介、安装和使用方法、案例应用之详细攻略 目录 gptpdf的简介 1、处理流程 第一步&#xff0c;使用 PyMuPDF 库&#xff0c;对 PDF 进行解析出所有非文本区域&#xff0c;并做好标记&#xff0c;比如: 第二步&#xff0c;使用视觉大模型&…

离婚后,孩子就读私立高中的高昂学费谁承担?

江苏省南京市六合区人民法院审结一起抚养费纠纷案件&#xff0c;认定夫妻双方在决定孩子教育事务上均存在责任&#xff0c;为保障临近高考的未成年子女的切身利益&#xff0c;认定由夫妻双方按比例承担教育费。   2015年6月&#xff0c;李某与王某离婚&#xff0c;双方之子小…

PCL 有序点云的法线估计(使用积分图进行法线估计)

使用积分图进行法线估计 一、概述1.1 概念1.2 有序点云与无序点云1.2.1 有序点云1.2.2 无序点云1.3 代码讲解二、代码实现三、结果示例一、概述 1.1 概念 使用积分图进行法线估计:计算一个有序点云的法线,注意该方法只适用于有序点云。 1.2 有序点云与无序点云 有序点云与无…

MySQL安装时initializing database失败

问题页面&#xff1a; 解决方法&#xff1a; 1.勾选红框中的选项&#xff1a; 2.将下图红框中全部改为英文&#xff1a; 然后一路next就可以了。

cs231n作业1——KNN

参考文章&#xff1a;assignment1——KNN KNN 测试时分别计算测试样本和训练集中的每个样本的距离&#xff0c;然后选取距离最近的k个样本的标签信息来进行分类。 方法1&#xff1a;Two Loops for i in range(num_test):for j in range(num_train):dist X[i, :] - self.X…

vue3使用方式汇总

1、引入iconfont阿里图库图标&#xff1a; 1.1 进入阿里图标网站&#xff1a; iconfont阿里&#xff1a;https://www.iconfont.cn/ 1.2 添加图标&#xff1a; 1.3 下载代码&#xff1a; 1.4 在vue3中配置代码&#xff1a; 将其代码复制到src/assets/fonts/目录下&#xff1…

Mysql之Using index for skip scan

一、Using index for skip scan 在 MySQL 中&#xff0c;EXPLAIN 语句用于显示查询执行计划&#xff0c;帮助我们理解查询是如何被执行的&#xff0c;以及如何优化查询。其中&#xff0c;Extra 列提供了关于查询执行的一些额外信息。当 Extra 列显示 Using index for skip sca…

CF F. Alex‘s whims

原题链接&#xff1a;Problem - 1899F - Codeforces 题目大意&#xff1a;要求构建出一颗树&#xff0c;多次询问树的叶节点之间的距离有没有达到要求的距离&#xff0c;如果有直接输出-1 -1 -1&#xff0c;如果没有可以断开一条边和连上一条边&#xff0c;输出x y z&#xff…

mp4视频太大怎么压缩不影响画质,mp4文件太大怎么变小且清晰度高

在数字化时代&#xff0c;我们常常面临视频文件过大的问题。尤其是mp4格式的视频&#xff0c;文件大小往往令人望而却步。那么&#xff0c;如何在不影响画质的前提下&#xff0c;有效地压缩mp4视频呢&#xff1f;本文将为您揭秘几种简单实用的压缩技巧。 在分享和存储视频时&am…

Open3D 计算点云的欧式距离

目录 一、概述 1.1欧式距离定义 1.2作用和用途 二、代码实现 2.1关键函数 2.2完整代码 三、实现效果 3.1原始点云 3.2处理后点云 一、概述 在Open3D中&#xff0c;compute_point_cloud_distance函数用于计算两个点云之间的距离。具体来说&#xff0c;它计算的是源点云…

【计算机网络仿真】b站湖科大教书匠思科Packet Tracer——实验16 路由信息协议RIP

一、实验目的 1.验证RIP协议的作用&#xff1b; 二、实验要求 1.使用Cisco Packet Tracer仿真平台&#xff1b; 2.观看B站湖科大教书匠仿真实验视频&#xff0c;完成对应实验。 三、实验内容 1.构建网络拓扑&#xff1b; 2.验证RIP协议。 四、实验步骤 1.构建网络拓扑 …