恒美微站 Logo 恒美微站
  • 首页
  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心
  • 联系我们

动态库的理解

  • 首页
  • 资讯中心
  • /
  • 动态库的理解

相关资讯

小白程序员快速上手大模型:打造实用Agent的收藏指南 2026/9/14 22:54:36
Wasp 路由与页面指南:用 route/page 声明式构建 React 应用 2026/9/14 22:54:36
数据驱动的DeePO-LQR控制算法实现与优化 2026/9/14 22:49:36

最新资讯

LangExtract:Python文本结构化处理的高效工具
DeepSeek v4.1 Flash 部署避坑指南:绕过DSH直调Pipeline API
C++异常处理机制详解与实践指南
为什么劝你在虚拟机里装Ubuntu?VMware+Ubuntu从零到实战完整指南
解决Jenkins Pipeline中Groovy脚本安全限制的实践指南
生物素化氨基酸:Biotin-L-Tyrosine的结构与应用

今日推荐

ASP+Access库存管理系统源码部署与IIS配置实战指南
基于SSM框架的毕业季旧物分类处理系统设计与实现
MATLAB FFT频谱仿真:从DFT原理到参数设置与窗函数选择

本周热门

AI SDK Harness 依赖更新指南:掌握 harness 包 SDK 依赖的升级、桥接同步与一致性校验
Refine v5 Ant Design NumberField 组件实战:基于 Intl 的本地化数字格式化
Flutter应用改名全指南:从Android到iOS的配置与工具实践

本月精选

自研推理加速器Redwood:两周内实现PyTorch模型高效部署的实战教程
V4L2摄像头采集实战:从camera_client.rar到出图全流程解析
从“谁发明了钢琴键”到知识问答智能体:RAG与记忆工程实践

动态库的理解

发布时间:2026/9/14 22:54:36
动态库的理解 上一篇中主要了解了下软硬链接,静态库和动态库 软硬链接及静动态库-CSDN博客这篇来简单学习下关于动态库的理解.这里主要与加载有关.从原理上理解动态库(共享库)动静态库都是文件,都有inode.库会映射到堆和栈之间的共享区上.进程使用库都是在自己的进程地址空间内完成.在要执行库方法时就跳到共享区上.多个进程要使用同一个动态库时,动态库不用重复加载,只需要把第一次使用时加载好的动态库加载到新要使用动态库的进程的地址空间中即可.动态库在内存中只需加载一份,可被多个进程共享.(所以叫共享库),节省空间.一起理解可以结合下图共享库可以加载到内存的任何地方,也可以映射到进程地址空间的任何地方,只要能找到就行,这就叫与地址无关.可执行程序的格式这里还需要了解下可执行程序的格式,在我另一篇博客中写过,如果感兴趣传送门在下可执行程序的格式-CSDN博客重谈地址空间(可执行程序加载)可执行程序一定要被操作系统识别.一些之前未解决的问题1.进程地址空间时操作系统申请并初始化的(因为地址空间时一个结构体对象,所以开始应该要初始化),但是要用谁的数据去初始化它呢?从可执行程序中来,读取可执行程序中的数据节来初始化代码段数据段.2.可执行程序(只是编译完,没有加载到内存时)有没有对应的地址?a.有地址!形成可执行程序就形成了天然的地址(逻辑地址)b.在ELF的section中的每一行代码都有自己的编址.每个段的编址是统一连续的,采用的时平坦模式(逻辑地址起始地址偏移量),平坦模式起始地址为0,所有的编址都是偏移量(从全0~全F)c.指令也有长度,在平坦模式下,下一条指令的地址-自己指令的地址就是自己指令的长度.d.只要找到第一个地址,程序从头向后就可以运行了.(指令长度已知).结论:ELF在没有加载到内存的时候就已经按照从全0~全F进行编址了.这就是虚拟地址,在编译器编译时就形成的.逻辑地址(磁盘)在数字上虚拟地址(内存).\补充:1.在程序内部用的地址(如函数调用等等)都用的是虚拟地址.2.并且程序加载到内存后要由CPU调度执行(这里涉及到之前提过的CPU内部的pc指针),pc指针会指向程序的开始(在ELF的头部中可以看到(见下))指向程序的入口函数,这时CPU调度的地址也是虚拟地址.程序执行时,使用的也是虚拟地址.3.程序加载到内存后不但有虚拟地址,也有自己对应的真实在内存中的地址(物理地址),就可以用这两个地址去完善页表了,建立起虚拟地址和物理地址的映射关系.CPU中的CR3寄存器就会存储页表的起始地址(是物理地址).4.CPU要拿着虚拟地址找到物理地址,这里需要CPU中的MMU硬件,它可以进行地址转化(也就是查表).CPU中出来的就是物理地址.找到地址后会把地址所在处的指令加载到CPU存储当前指令的寄存器EIP中.之后pc指针根据指令长度增加,找到下一个虚拟地址,继续地址转化拿到指令执行,如此循环.虚拟地址空间时操作系统,CPU,编译器三方共同作用下的产物.3.为什么要有虚拟地址和虚拟地址空间?编译器在编译时不用思考物理地址了,把编译器和操作系统解耦了.重谈区域划分之前谈到了代码段,初始化数据区和未初始化数据区的划分都在程序编译时进行,那么堆,栈,共享区这些改怎么划分呢?我们要引入一个vm_area_struct的结构体.vm_area_struct是一个链表(是虚拟地址空间的主要构成),里面存储着一个个区域节点(这些区域存的是虚拟地址,也要进行页表映射才能找到物理地址),链接到一起就构成了堆,栈,共享区以及代码段,初始化数据区,未初始化数据区.地址空间的结构体(mm_struct)中有一个指针指向vm_area_struct.这个链表结构支持了虚拟地址空间进行很多动态变化,也支持可执行程序的分批加载.地址空间大致就如下图所示.其实我们要执行程序时可以只把起始虚拟地址加载到CPU的pc指针处,之后CPU进行寻址,找不到的话在进行懒加载即可.简单了解动态库的加载地址重定位的方式进行加载.用动态库时再把动态库加载到内存,先把动态库的虚拟地址加入到虚拟地址空间中,并且把对应的方法替换为库名:方法虚拟地址,库加载到内存后再把库名替换为库对应的虚拟空间起始的虚拟地址即可.这样就可以实现与库地址无关了.(结合下图理解)其实代码区为只读不能进行上述替换,但是为了好理解就先这么想,真实的情况要复杂很多,是通过改ELF中的偏移量表GOT实现的(我们只做简单理解即可).GOT是每个进程都有的.GOT库方法偏移量与地址无关.

关于恒美微站

恒美微站专注于为个体商户、工作室提供极简自助建站服务,让每个人都能轻松拥有专业网站。

快速链接

  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心

服务项目

  • 可视化建站
  • 拖拽编辑
  • 主题定制
  • SEO 优化
  • 网站托管

联系方式

  • 📍 地址:北京市朝阳区建国路 88 号
  • 📞 电话:400-888-8888
  • ✉️ 邮箱:info@hmyw.cn
  • 🕐 时间:周一至周日 9:00-18:00

© 2024 恒美微站 hmyw.cn 版权所有 | 京 ICP 备 12345678 号