当前位置: 首页 > news >正文

《程序员的自我修养》阅读笔记

文章目录

  • 【第2部分】静态链接
    • 1 编译过程
    • 2 编辑器的工作流程
    • 3 链接——模块的拼接
    • 4 目标文件
      • 目标文件中的段(section)
      • ELF文件结构
    • 5 静态链接
      • 1 空间与地址分配
      • 2 符号解析与重定位
  • 【第3部分】装载与动态链接
    • 1 装载的方式
    • 2 进程的启动
    • 3 为什么需要动态链接?
    • 4 动态链接的基本实现
    • 5 位置无关码(PIC)
    • 6 显式运行时链接(Explicit Run-time Linking)

【第2部分】静态链接

在这里插入图片描述

1 编译过程

  1. 预编译
    预编译将源文件和包含的头文件编排成xx.i的预编译文件,主要是将#include的文件内容替换进源文件,并且将宏定义(#define)展开,还有处理预编译指令(#if#ifdef等)以及删除注释等等。
  2. 编译
    简单来说就是将C语言代码转换成汇编代码;
  3. 汇编
    汇编器将汇编代码转换成机器码,产出一个xx.o目标文件;
  4. 链接
    对目标文件进行编排,组合成可执行文件或者库(目标文件的包)。

2 编辑器的工作流程

词法分析->语法分析->语义分析->源代码优化->目标代码生成和优化。

3 链接——模块的拼接

问题引入:当一个程序被分割成多个模块时,最终如何组成的一个可执行程序?

链接的过程包括:

  • 地址和空间分配
  • 符号决议(symbol resolution),或符号绑定(symbol binding)
  • 重定位(relocation)——给程序中引用某个绝对地址的指令打补丁

链接器会根据指令所引用的符号,找到符号的地址,然后修正指令。

4 目标文件

Linux上,我们统称目标文件和可执行文件为ELF格式的文件,广义上他们几乎是一样的。

ELF文件有以下4大类:

  1. Relocatable File —— xx.o
  2. Executable File
  3. Shared Object File —— .so
  4. Core Dump File

目标文件中的段(section)

在这里插入图片描述
在这里插入图片描述

ELF文件结构

  1. 文件头-ELF Header
    可以使用readelf -h xx.o来查看文件头。
  2. 段表-Section Header Table
    使用readelf -S来查看ELF文件包含的段。
  3. 重定位表-Relocation Table0
    .rel.text.rel.data,记录重定位信息
  4. 字符串表
    把字符串集中起来存放到一个表里,然后通过使用偏移地址来引用字符串(结尾为空字符),包括.strtab(符号名的字符串)和.shstrtab(段名的字符串)

5 静态链接

1 空间与地址分配

扫描所有目标文件,收集所有的符号定义和符号引用,放到全局符号表中;计算出各个文件的各个段在合并后的位置以及长度,建立映射关系。

2 符号解析与重定位

在编译文件时,一些函数是在外部文件中定义的,编译器并不知道它的地址,就暂时将它们的地址设为0,真正的地址计算和修改则留给链接器。

那么链接器如何知道哪些指令中使用的地址需要重定位?这时就轮到重定位表发挥作用了,重定位表记录了每个符号的入口地址在表中的偏移地址。

【第3部分】装载与动态链接

1 装载的方式

  1. 覆盖装入:由程序员管理模块何时被加载到内存,该方式已被淘汰
  2. 页映射:以页为单元在磁盘和内存之间装载或置换数据

2 进程的启动

  1. 创建虚拟地址空间(通过MMU映射到物理内存)
  2. 读取可执行文件的文件头,建立虚拟地址空间和可执行文件的映射关系(用于加载可执行文件所在的页到内存)
  3. 将CPU指令寄存器设置成可执行文件入口

3 为什么需要动态链接?

  • 只使用静态链接,会造成内存和磁盘的浪费;
  • 使用静态链接时,如果某个模块更新,那么整个程序都要重新编译;

动态链接:等到程序开始运行时才进行链接。

4 动态链接的基本实现

程序装载时,动态链接器将所需要的动态库装载到进程地址空间,将所有未决议的符号绑定到相应的动态链接库,并进行重定位工作。

为了优化程序装载时进行链接的性能问题,采取了延迟绑定等方法。

cat /proc/xxxx/maps即可查看某个进程的的虚拟地址空间分布,其中可以看到部分引用的.so动态库所被映射的位置,其中有一个库为ld-x.x.so,这实际上就是linux的动态链接器,进程运行前会先跳转到动态链接器的代码中运行,完成链接工作后再跳转回进程代码运行。

5 位置无关码(PIC)

装载时重定位——把动态库的重定位也推迟到装载时进行。但有一个问题,动态链接库的代码在多个进程间共享,而重定位需要修改其指令,每个进程需要的修改可能不一样(比如跳转的地址不一样),那么就没法共享了。

PIC的基本思想:将指令中需要修改的部分分离出来,放到数据段中,这样指令部分就可以保持不变,而数据段对于每个进程都是有自己的独一份的。

模块间的数据访问:在数据段里建立一个指向外部变量的指针数组,即全局偏移表(Global Offset Table,GOT)。在编译时即确定GOT相对于当前指令的偏移,同时确定GOT中每个地址对应于哪个变量;模块装载时,加载器查找每个变量的实际地址,填充GOT的各个项。

如何区分动态库是否为PIC:readelf -d xx.so | grep TEXTREL,如果输出为空,则不是PIC。so库必须是PIC才能真正实现共享。

6 显式运行时链接(Explicit Run-time Linking)

或者叫运行时加载,即程序运行时自己指定加载的模块,且可以在不需要时将模块卸载。这可以用来实现插件、驱动等。程序可以通过4个API对动态库进行操作:

  • dlopen():加载动态库到进程地址空间
  • dlsym():找到所需的符号所在的地址
  • dlclose():卸载模块
  • dlerror():调用上面3个函数后,可以通过调用该函数判断前者调用是否成功

相关文章:

《程序员的自我修养》阅读笔记

文章目录【第2部分】静态链接1 编译过程2 编辑器的工作流程3 链接——模块的拼接4 目标文件目标文件中的段(section)ELF文件结构5 静态链接1 空间与地址分配2 符号解析与重定位【第3部分】装载与动态链接1 装载的方式2 进程的启动3 为什么需要动态链接&a…...

【跟着ChatGPT学深度学习】ChatGPT带我入门深度学习

❤️觉得内容不错的话,欢迎点赞收藏加关注😊😊😊,后续会继续输入更多优质内容❤️👉有问题欢迎大家加关注私戳或者评论(包括但不限于NLP算法相关,linux学习相关,读研读博…...

软工2023个人作业一——阅读和提问

项目内容这个作业属于哪个课程2023年北航敏捷软件工程这个作业的要求在哪里个人作业-阅读和提问我在这个课程的目标是学习并掌握现代软件开发和项目管理技术,体验敏捷开发工作流程这个作业在哪个具体方面帮助我实现目标通读《构建之法》,了解软件工程中基…...

【Redis】线程模型:Redis是单线程还是多线程?

【Redis】线程模型:Redis是单线程还是多线程? 文章目录【Redis】线程模型:Redis是单线程还是多线程?Redis 是单线程吗?Redis 单线程模式是怎样的?Redis 采用单线程为什么还这么快?Redis 6.0 之前…...

FSM(有限状态机)

FSM有限状态机FSM创建控制有限状态机的脚本设置FSM状态机下的各个状态添加测试类FSM的优点FSM 虽然Unity已经有了动画状态机,但是为了代码的开放封闭原则,这时FSM有限状态机的作用就凸显了出来。 创建控制有限状态机的脚本 先创建一个脚本用来控制有限…...

奇妙的background-clip:text

我们在学习CSS3时,一个背景属性background-clip用来对背景进行裁剪,即指定背景绘制的区域,通常我们使用的几个属性如下:值说明border-box默认值。背景绘制在边框方框内(剪切成边框方框)。padding-box背景绘…...

Vmware虚拟机无法联通主机解决方法二

昨天在遇到了VMware 虚拟机无法联通主机,导致我在CentOS-7 搭建的伪Hadoop3 服务,无法访问管理平台,使用将网络编辑器修改为“桥接”模式解决。今天在学习HBase 时,昨天的问题又重新了,我通过SSH 工具MobaXterm 都无法…...

Boost资料整理备忘

Boost资料整理备忘 网络资源 书籍: The Boost C Libraries官方文档 Boost Library Documentation random boost.randomBoost随机库的简单使用:Boost.Random(STL通用)tutorialstd::random boost::asio Boost.Asio 网络编程 - 基本原理Boost.Asio DocBoost定时器 网…...

规则引擎与风控系统01:新问题,新挑战

如果说在支付系统中使用设计模式,以及开发自定义协议的物联网这两类应用还不够酷的话,那么接下来,咱们就来学一点高逼格的技术吧。 在互联网已经日益普遍的时代,不管是开发2C应用还是2B应用,相信大部分的开发者都有过处理复杂业务逻辑的经历,比如电商、社交、电子政务、O…...

Oracle-00-卸载篇

这里给出企业级的Oracle 10g的卸教程,新安装的19c并没有正经去做卸载的操作,为了后面教程的进度,这里就先借用下10g,如果有需要会重新更新19c的卸载教程 windows服务中将Oracle所有服务全部停掉 选中Oracle - OraDb10g_home2->Oracle Installation Products->Univers…...

Java线程池使用与原理解析1(线程池优点、使用方法、参数含义及线程池运转机制)

为什么要使用线程池? JDK1.5后JUC包添加了线程池相关接口,在Java诞生之初并没有线程池这个概念。刚开始Java程序都是自行创建线程去处理任务。随着应用使用的线程越来越多,JDK开发者们发现有必要使用一个统一的类来管理这些线程,…...

windows下编译leveldb(动态库+静态库)

环境准备 1)下载cmake并安装 下载路径: https://cmake.org/download/2)下载leveldb源码 git clone https://github.com/google/leveldb.git3)下载googletest和benchmark,cmake编译时需要 # 进入leveldb源码路径下的third_part…...

如何用76行代码写一个AI微信机器人......

本期博客主要介绍如何使用 微信SDK 和 AI聊天接口 ,实现 微信机器人功能。 准备 电脑需要安装Go环境,这个可以直接参考菜鸟教程:Go 语言环境安装,知道CSDN的同学基本能在半小时内装好吧…(可选)一个编译器…...

拿下域控后,我还是对大佬的操作念念不忘

历来攻防演练中,我都笃信一个道理——吃饱了才有力气干活。所以,在清晨的客户现场,当看到大佬满意地吃完了我带来的煎饺,我知道这一战,我们作为攻击队,基本已经拿下了。 虽然说的每一句话都带着一股醋味儿…...

实习-----Mybatis 框架

Mybatis 框架ORM持久化介绍 了解什么是“持久化”即把数据(如内存中的对象)保存的磁盘的某一文件中ORM概念ORM,即Object Relational Mapping,它是对象关系映射的简称。它的作用是在关系型数据库和对象之间作一个映射,是…...

【Linux】孤儿进程 | 环境变量 | 命令行参数 | 进程优先级

文章目录1. 孤儿进程2. 环境变量1. PATH环境变量证明ls是系统指令修改自己写的可执行程序对应路径2. env——查看系统环境变量3. 获取环境变量envpenvirongetenv 函数获取 (主流)4. 总结3 . 命令行参数理解命令行参数4. 进程优先级优先级与权限的区分为什么会有优先级&#xff…...

Matlab字符串相关操作-拼接、格式化

常见的有三种方法:向量拼接、strcat函数和sprintf函数1、向量拼接在matlab中字符串本质上也是一个向量,可以通过矩阵运算来实现字符串的拼接,这里随便输入两个字符串a1和b1,用矩阵形式进行拼接:a1 I love;b1 Matlab…...

死磕Spring系列,SpringBoot启动流程

参考文章:SpringBoot启动流程系列讲解 参考视频:SpringBoot启动流程 吐血推荐视频:史上最完整的Spring启动流程 超级好文:SpringBoot执行原理 参考文章:SpringBoot资源接口ResourceLoader和Resource学习 参考文章&…...

关于条件变量wait操作中锁的作用

condition_variable::wait的锁 在看C Concurrency in Action 6.2.3节的线程安全队列时,其对condition_variable的使用与常规用法有点不同,我对condition_variable::wait中锁的作用产生了疑惑:它究竟是保护的谁?于是找到了 C noti…...

JUC并发编程与源码分析笔记09-原子类操作之十八罗汉增强

基本类型原子类 AtomicInteger、AtomicBoolean、AtomicLong。 常用API: public final int get();// 获取当前的值 public final int getAndSet(int newValue);// 获取当前值,并设置新值 public final int getAndIncrement();// 获取当前的值&#xff0…...

vscode里如何用git

打开vs终端执行如下: 1 初始化 Git 仓库(如果尚未初始化) git init 2 添加文件到 Git 仓库 git add . 3 使用 git commit 命令来提交你的更改。确保在提交时加上一个有用的消息。 git commit -m "备注信息" 4 …...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院挂号小程序

一、开发准备 ​​环境搭建​​: 安装DevEco Studio 3.0或更高版本配置HarmonyOS SDK申请开发者账号 ​​项目创建​​: File > New > Create Project > Application (选择"Empty Ability") 二、核心功能实现 1. 医院科室展示 /…...

376. Wiggle Subsequence

376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...

Python实现prophet 理论及参数优化

文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候&#xff0c;写过一篇简单实现&#xff0c;后期随着对该模型的深入研究&#xff0c;本次记录涉及到prophet 的公式以及参数调优&#xff0c;从公式可以更直观…...

Qt Http Server模块功能及架构

Qt Http Server 是 Qt 6.0 中引入的一个新模块&#xff0c;它提供了一个轻量级的 HTTP 服务器实现&#xff0c;主要用于构建基于 HTTP 的应用程序和服务。 功能介绍&#xff1a; 主要功能 HTTP服务器功能&#xff1a; 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...

HBuilderX安装(uni-app和小程序开发)

下载HBuilderX 访问官方网站&#xff1a;https://www.dcloud.io/hbuilderx.html 根据您的操作系统选择合适版本&#xff1a; Windows版&#xff08;推荐下载标准版&#xff09; Windows系统安装步骤 运行安装程序&#xff1a; 双击下载的.exe安装文件 如果出现安全提示&…...

什么是EULA和DPA

文章目录 EULA&#xff08;End User License Agreement&#xff09;DPA&#xff08;Data Protection Agreement&#xff09;一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA&#xff08;End User License Agreement&#xff09; 定义&#xff1a; EULA即…...

NFT模式:数字资产确权与链游经济系统构建

NFT模式&#xff1a;数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新&#xff1a;构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议&#xff1a;基于LayerZero协议实现以太坊、Solana等公链资产互通&#xff0c;通过零知…...

【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)

骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术&#xff0c;它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton)&#xff1a;由层级结构的骨头组成&#xff0c;类似于人体骨骼蒙皮 (Mesh Skinning)&#xff1a;将模型网格顶点绑定到骨骼上&#xff0c;使骨骼移动…...

IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)

文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...