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.mfbz.cn/a/784475.html

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

相关文章

49.实现调试器HOOK机制

免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动! 上一个内容:47.HOOK引擎优化支持CALL与JMP位置做HOOK 以 47.HOOK引擎优化支持CALL与JMP位置做HOOK 它的代码为基础进行修改 效果图:游…

Mysql8.0.36 Centos8环境安装

下载安装包 官网地址:MySQL :: Download MySQL Community Server (Archived Versions) 可以直接下载后再传到服务器,也可以在服务器采用wget下载。如下: wget https://downloads.mysql.com/archives/get/p/23/file/mysql-8.0.36-linux-glib…

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

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

ELK+Filebeat+Kafka+Zookeeper

本实验基于ELFK已经搭好的情况下 ELK日志分析 架构解析 第一层、数据采集层 数据采集层位于最左边的业务服务器集群上,在每个业务服务器上面安装了filebeat做日志收集,然后把采集到的原始日志发送到Kafkazookeeper集群上。第二层、消息队列层 原始日志发…

运维锅总详解系统设计原则

本文对CAP、BASE、ACID、SOLID 原则、12-Factor 应用方法论等12种系统设计原则进行分析举例,希望对您在进行系统设计、理解系统运行背后遵循的原理有所帮助! 一、CAP、BASE、ACID简介 以下是 ACID、CAP 和 BASE 系统设计原则的详细说明及其应用举例&am…

降Compose十八掌之『飞龙在天』| Layout

公众号「稀有猿诉」 原文链接 降Compose十八掌之『飞龙在天』| Layout 页面布局是GUI应用开发的核心,决定着一个UI具体如何实现。今天将延着路线图来练习『降Compose十八掌』的第二招式,学习一下如何使用Compose中的布局来构建页面。 基础骨架 基…

前端vue打印后端对象为[object,object]

今天给自己项目进行编写前端页面时,惊讶的发现,自己进行打印后端传递的对象,一直显示未[object,object],如下图所示: 感觉很奇怪,于是我猜测是不是自己获取的返回数据的问题,在进行添加了datat…

Windows10/11家庭版开启Hyper-V虚拟机功能详解

Hyper-V是微软的一款虚拟机软件,可以使我们在一台Windows PC上,在虚拟环境下同时运行多个互相之间完全隔离的操作系统,这就实现了在Windows环境下运行Linux以及其他OS的可能性。和第三方虚拟机软件,如VMware等相比,Hyp…

云计算【第一阶段(28)】DNS域名解析服务

一、DNS解析的定义与作用 1.1、DNS解析的定义 DNS解析(Domain Name System Resolution)是互联网服务中的一个核心环节,它负责将用户容易记住的域名转换成网络设备能够识别和使用的IP地址。一般来讲域名比 IP 地址更加的有含义、也更容易记住…

202487读书笔记|《我有个拥抱,你要不要》——生活从来如此,你的态度赋予它意义

202487读书笔记|《我有个拥抱,你要不要》——生活从来如此,你的态度赋予它意义 《我有个拥抱,你要不要》作者一天到晚气fufu,挺有愛的小漫画,适合用来看图说话锻炼小语言,我看的很快乐也写得很痛快&#xf…

打卡第6天----哈希表

每天进步一点点,滴水石穿,日积月累,不断提升。 数组和链表章节告一段落。开启哈希表相关的。 哈希表能解决什么问题呢,一般哈希表都是用来快速判断一个元素是否出现集合里 一、有效的字母异位词 leetcode题目编号:242 题目描述: 给定两个字符串 s 和 t ,编写一个函数…

国内教育科技公司自研大语言模型

好未来的数学大模型九章大模型(MathGPT) 2023年8月下旬,在好未来20周年直播活动中,好未来公司CTO田密宣布好未来自研的数学领域千亿级大模型MathGPT正式上线并开启公测。根据九章大模型的官网介绍,九章大模型&#xff…

语言模型的进化:从NLP到LLM的跨越之旅

在人工智能的浩瀚宇宙中,自然语言处理(NLP)一直是一个充满挑战和机遇的领域。随着技术的发展,我们见证了从传统规则到统计机器学习,再到深度学习和预训练模型的演进。如今,我们站在了大型语言模型&#xff…

搭建基础库~

前言 项目中会用到工具库、函数库以及一些跟框架绑定的组件,如果这些基础模块每个项目都实现一套,维护起来那真的头大,你说呢😉 搭建流程 准备工作 创建文件夹myLib、安装Git以及pnpm 目录大概就系这样子: myLib ├…

你真的会信息收集嘛,4k字渗透测试信息收集10大技巧

前言 在渗透测试中,信息收集是非常关键的一步,它为后续的漏洞发现和利用提供了重要的基础。以下是非常详细的信息收集方式: 一、被动信息收集 被动信息收集是指在不与目标系统直接交互的情况下,通过公开渠道获取目标系统的相关…

LabVIEW在半导体自动化测试中的应用

半导体制造的复杂性和精密度要求极高,每一个生产步骤都需要严格的控制和监测。自动化测试设备在半导体制造中起到了关键作用,通过精密测量和数据分析,确保产品质量和生产效率。本文介绍如何使用LabVIEW结合研华硬件,开发一个用于半…

Nacos注册中心相关错误记录

文章目录 1,com.alibaba.cloud:spring-cloud-starter-alibaba-nacos-discovery:jar:unknown was not found1.1 定位及解决方案1.2,简要说明dependencyManagement的作用 2,nacos启动失败2.1 解决方案 1,com.alibaba.cloud:spring-c…

白嫖A100活动来啦,书生·浦语大模型全链路开源体系

扫码参加即可获得: 第一节 书生浦语大模型全链路开源体系 书生浦语大模型的开源历程。 从模型到应用的典型流程 书生浦语的开源体系,包含从数据、预训练、微调、部署、评测、应用等环节

无线领夹麦克风品牌排名,揭秘国产领夹麦克风哪个品牌好

在自媒体行业迅猛发展的浪潮中,领夹麦克风作为音频采集的关键设备,其市场需求正经历着前所未有的激增。面对市场上众多品牌和型号的选择,如何做出既符合个人需求又不失专业水准的决策,成为了消费者亟待解决的问题。 我特意为大家…

逻辑回归中的损失函数

一、损失函数介绍: 与回归问题成本函数不同的是,逻辑回归模型(解决分类问题)的成本函数在获得损失J的时候不再用真实值y与预测值y^的差值计算损失,真实值y不再出现在公式中作为计算项。 首先,该次训练损失…