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.rhkb.cn/news/372403.html

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

相关文章

Java基础---复习01

main方法 一个程序有且只有一个main方法,main方法是java程序的唯一入口。 修饰符 修饰类修饰方法修饰域public都可以访问都可以访问private私有类只能本类只能本类protected子类可以继承、访问,同包下的类也可以访问子类可以继承、访问,同…

[AI 大模型] Google Gemini

文章目录 [AI 大模型] Gemini简介模型架构发展新技术和优势示例 [AI 大模型] Gemini 简介 Google Gemini 是 Google 最新推出的多模态 AI 大模型,旨在提升 AI 在各个领域的应用能力。Gemini 能够处理文本、图像、音频、视频和代码等多种数据类型,展现出…

暑期备考2024小学生古诗文大会:吃透真题和知识点(持续)

2024年上海市小学生古诗文大会的自由报名初赛将于10月19日(星期六)正式开始,还有3个多月的时间。 为帮助孩子们备考,我持续分享往年上海小学生古诗文大会真题,这些题目来自我去重、合并后的1700在线题库,每…

云计算渲染时代:选择Blender或KeyShot进行高效渲染

在云渲染技术日益成熟的背景下,挑选一款贴合项目需求的3D渲染软件显得尤为关键。当前,Blender与KeyShot作为业界领先的全能渲染解决方案,广受推崇。它们虽皆能创造出令人信服的逼真视觉效果,但在特色功能上各有所长。本篇文章旨在…

稀疏建模介绍,详解机器学习知识

目录 一、什么是机器学习?二、稀疏建模介绍三、Lasso回归简介四、Lasso超参数调整与模型选择 一、什么是机器学习? 机器学习是一种人工智能技术,它使计算机系统能够从数据中学习并做出预测或决策,而无需明确编程。它涉及到使用算…

华为HCIP Datacom H12-821 卷30

1.单选题 以下关于OSPF协议报文说法错误的是? A、OSPF报文采用UDP报文封装并且端口号是89 B、OSPF所有报文的头部格式相同 C、OSPF协议使用五种报文完成路由信息的传递 D、OSPF所有报文头部都携带了Router-ID字段 正确答案:A 解析: OSPF用IP报…

游戏AI的创造思路-技术基础-决策树(1)

决策树,是每个游戏人必须要掌握的游戏AI构建技术,难度小,速度快,结果直观,本篇将对决策树进行小小解读~~~~ 目录 1. 定义 2. 发展历史 3. 决策树的算法公式和函数 3.1. 信息增益(Information Gain&…

无线网卡怎么连接台式电脑?让上网更便捷!

随着无线网络的普及,越来越多的台式电脑用户希望通过无线网卡连接到互联网。无线网卡为台式电脑提供了无线连接的便利性,避免了有线网络的束缚。本文将详细介绍无线网卡怎么连接台式电脑的四种方法,包括使用USB无线网卡、内置无线网卡以及使用…

终于搞定了通过两路蓝牙接收数据

一直想做无线传感器,通过蓝牙来接收数据,无奈因为arduino接收串口数据的一些问题,一直搁到现在。因为学校里给学生开了选修课,所以手边有一些nano和mega可以使用,所以就做了用两个nano加上两个蓝牙模块来发射数据&…

群体优化算法---文化算法介绍,求解背包问题

介绍 文化算法(Cultural Algorithm, CA)是一种基于文化进化理论的优化算法,首次由Robert G. Reynolds在20世纪90年代提出。文化算法通过模拟人类社会中的文化进化过程,利用个体与群体的双重进化机制来解决优化问题。其基本思想是…

动态数据库设计

动态数据库设计是一种灵活的方法,用于构建能够适应不断变化的数据需求的数据库结构。它强调在不频繁修改数据库表结构的前提下,有效管理和存储多样化的数据。以下是实现动态数据库设计的一些关键技术点和策略: 实体-属性-值(EAV&a…

Java的面向对象基础

叠甲:以下文章主要是依靠我的实际编码学习中总结出来的经验之谈,求逻辑自洽,不能百分百保证正确,有错误、未定义、不合适的内容请尽情指出! 文章目录 1.面向过程和面向对象2.访问限定符3.类和对象基础3.1.类的定义3.2.…

【安全设备】下一代防火墙

一、什么是防火墙 防火墙是一个网络安全产品,它是由软件和硬件设备组合而成,在内网和外网之间、专用网与公共网之间的一种保护屏障。在计算机网络的内网和外网之间构建一道相对隔离的保护屏障,以达到保护资料的目的。它是一种隔离技术&#…

Qt 线程 QThread类详解

Qt 线程中QThread的使用 在进行桌面应用程序开发的时候, 假设应用程序在某些情况下需要处理比较复杂的逻辑, 如果只有一个线程去处理,就会导致窗口卡顿,无法处理用户的相关操作。这种情况下就需要使用多线程,其中一个…

【操作系统】进程管理——进程的同步与互斥(个人笔记)

学习日期:2024.7.8 内容摘要:进程同步/互斥的概念和意义,基于软/硬件的实现方法 进程同步与互斥的概念和意义 为什么要有进程同步机制? 回顾:在《进程管理》第一章中,我们学习了进程具有异步性的特征&am…

如何安全隐藏IP地址,防止网络攻击?

当您想在互联网上保持隐私或匿名时,您应该做的第一件事就是隐藏您的 IP 地址。您的 IP 地址很容易被追踪到您,并被用来了解您的位置。下面的文章将教您如何隐藏自己,不让任何试图跟踪您的活动的人发现。 什么是 IP 地址? 首先&am…

JavaWeb系列二十一: 数据交换和异步请求(JSON, Ajax)

文章目录 官方文档JSON介绍JSON快速入门JSON对象和字符串对象转换应用案例注意事项和细节 JSON在java中使用说明JSON在Java中应用场景应用实例1.3.3 Map对象和JSON字符串转换 2. Ajax介绍2.1 Ajax应用场景2.2 传统的web应用-数据通信方式2.3 Ajax-数据通信方式2.4 Ajax文档使用…

百度云智能媒体内容分析一体机(MCA)建设

导读 :本文主要介绍了百度智能云MCA产品的概念和应用。 媒体信息海量且复杂,采用人工的方式对视频进行分析处理,面临着效率低、成本高的困难。于是,MCA应运而生。它基于百度自研的视觉AI、ASR、NLP技术,为用户提供音视…

标准盒模型和怪异盒子模型的区别

盒模型描述了一个 HTML 元素所占用的空间,由内容(content)、内边距(padding)、边框(border)和外边距(margin)组成。 可以通过修改元素的box-sizing属性来改变元素的盒模型…

idea 默认路径修改

1.查看 idea 的安装路径(右键点击 idea 图标,查看路径 ) “C:\Program Files\JetBrains\IntelliJ IDEA 2021.3.1\bin\idea64.exe” 在 bin 目录查看 idea.properties 文件,修改以下四个路径文件 # idea.config.path${user.home}/…