程序的链接有以下三种方式:

  • 静态链接:在程序运行之前,先将各目标模块及它们所需的库函数链接成一个完整的可执行程序,以后不再拆开。
  • 装入时动态链接:将用户源程序编译后所得到的一组目标模块,在装入内存时,釆用边装入边链接的链接方式。
  • 运行时动态链接:对某些目标模块的链接,是在程序执行中需要该目标模块时,才对它进行的链接。其优点是便于修改和更新,便于实现对目标模块的共享。

  模块在装入内存时,同样有以下三种方式:

  • 绝对装入。在编译时,如果知道程序将驻留在内存的某个位置,编译程序将产生绝对地址的目标代码。绝对装入程序按照装入模块中的地址,将程序和数据装入内存。由于程序中的逻辑地址与实际内存地址完全相同,故不需对程序和数据的地址进行修改。编译过程中就确定了程序运行时的物理地址。
  • 可重定位装入。在多道程序环境下,多个目标模块的起始地址通常都是从0开始,程序中的其他地址都是相对于起始地址的,此时应釆用可重定位装入方式。根据内存的当前情况,将装入模块装入到内存的适当位置。装入时对目标程序中指令和数据的修改过程称为重定位,地址变换通常是在装入时一次完成的,所以又称为静态重定位。静态重定位的特点是在一个作业装入内存时,必须分配其要求的全部内存空间,如果没有足够的内存,就不能装入该作业。此外,作业一旦进入内存后,在整个运行期间不能在内存中移动,也不能再申请内存空间。
  • 动态运行时装入,也称为动态重定位,程序在内存中如果发生移动,就需要釆用动态的装入方式。装入程序在把装入模块装入内存后,并不立即把装入模块中的相对地址转换为绝对地址,而是把这种地址转换推迟到程序真正要执行时才进行。因此,装入内存后的所有地址均为相对地址,这种方式需要一个重定位寄存器的支持。动态重定位的特点是可以将程序分配到不连续的存储区中;在程序运行之前可以只装入它的部分代码即可投入运行,然后在程序运行期间,根据需要动态申请分配内存;便于程序段的共享,可以向用户提供一个比存储空间大得多的地址空间。

地址重定位就是操作系统将逻辑地址转变为物理地址的过程 也就是对目标程序中的指令和数据进行修改的过程

将逻辑地址空间重定位到物理地址空间的时机有三种:

  1、程序编译连接时。

  2、程序装入内存时。(静态地址重定位)

  3、程序执行时(动态地址重定位)

以下内容转自:http://bbs.pediy.com/showthread.php?t=76876

  在这之前我一直对地址重定位的细节不是很了解。以下文章摘自《操作系统原理DOS篇(第二版)》。是我目前看过的关于重定位的最好的文章。与大家分享 一下。
  以下介绍程序是如何装入内存,从而变成在计算机内可执行的形式的。
  在用汇编语言或高级语言编写的程序中,是通过符号名来访问子程序和数据的,我们把程序中符号名的集合叫做“名字空间”。汇编语言源程序经过汇编,或者高级语言源程序经过编译,得到的目标程序是以“0”作为参考地址的模块,然后多个目标模块由连接程序连接成一个具有统一地址的装配模块,以便最后装入内存中执行。我们把目标模块obj中的地址称为相对地址(或逻辑地址),而把相对地址的集合叫做“相对地址空间”或简单地叫做“地址空间”。
  装配模块虽然具有统一的地址空间,但它仍是以“0”作为参考地址,即是浮动的。要把它装入内存执行,就要确定装入内存的实际物理地址,并修改程序中与 地址有关的代码,这一过程叫做地址重定位。
  地址空间的程序和数据经过地址重定位处理后,就变成了可由CPU直接执行的绝对地址程序。我们把这一地址集合称为“绝对地址空间”或“存储空间”。

  地址重定位完成的相对地址转换成内存的绝对地址工作又称为地址映射(map)、按照重定位的时机,可分为静态重定位和动态重定位。

一、静态重定位
  静态重定位是在程序执行之前进行重定位,它根据装配模块将要装入的内存起始位置,直接修改装配模块中的有关使用地址的指令。程序在装入的过程中,修改相关的地址指令。
  例如,一个以“0”作为参考地址的装配模块,要装入以100为起始地址的存储空间。显然,在装入之前要做某些修改,程序才能正确执行。例如,MOV  EAX,[500]这条指令的意义,是把相对地址为500的存储单元内容1234装入EAX号累器。现在内容为1234的存储单元的实际地址为1500, 即为相对地址(500)加上装入的地址(1000),因此,MOV EAX,[500]这条指令中的直接地址码也要相应地加上起始地址,而成为MOV  EAX,[1500]。
  程序中涉及直接地址的每条指令都要进行这样的修改。需要修改的位置称为重定位项,所做的加实际装入模块起始地址修改中的块起始地址称为重定位因子。
  为支持静态重定位,连接程序在生成统一地址空间和装配模块时, 应产生一个重定位项表,连接程序此时还不知道装配模块将要装入的实际位置,故重定位表 所给出的需修改位置是相对地址所表示的位置。
  操作系统的装入程序要把装配模块和重定位项表一起装入内存。由装配模块的实际装入起始地址得到重定位因子,然后实施如下两步:
  (1)取重定位项,加上重定位因子而得到欲修改位置的实际地址;
  (2)对实际地址中的内容再做加重定位因子的修改,从而完成指令代码的修改。
  对所有的重定位项实施上述两步操作后,静态重定位才完成,尔后可启动程序执行。使用过的重定位项表内存副本随即被废弃。
  静态重定位有着无需硬件支持的优点,但存在着如下的缺点:一是程序重定位之后就不能在内存中搬动了;二是要求程序的存储空间是连续的,不能把程序放在若干个不连续的区域内。

二、动态重定位
  动态重定位是指,不是在程序执行之前而是在程序执行过程中进行地址重定位。更确切地说,是在CPU每次访问内存单元前才进行地址变换。动态重定位可使装配模 块不加任何修改而装入内存,但是它需要硬件——定位寄存器的支持。
  程序的目标模块装入内存时,与地址有关的各项均保持原来的相对地址不进行任何修改。如MOV 1,[500]这条指令仍是相对地址500。当此模块被 操作系统调度到处理机上执行时,操作系统将把此模块装入的实际起始起始地址减去目标模块的相对基地址,然后将其差值装入定位寄存器中。当CPU取得一条访 问内存的指令时,地址变换硬件逻辑自动将指令中的相对地址与定位寄存器中的值相加,再依此和值作为内存绝对地址去访问该单元中的数据。
  由此可见,进行动态重定位的时机是在指令执行过程中,每次访问内存前动态地进行。采取动态重定位可带来两个好处:
  (1)目标模块装入内存时无需任何修改,因而装入之后再搬迁也不会影响其正确执行,这对于存储器紧缩、解决碎片问题是极其有利的;
  (2)一个程序由若干个相对独立的目标模块组成时,每个目标模块各装入一个存储区域,这些存储区域可以不是顺序相邻的,只要各个模块有自己对应的定位寄存器就行。

  动态重定位技术所付出的代价是需要硬件支持。

总结:

静态地址重定位:即在程序装入内存的过程中完成,是指在程序开始运行前,程序中的各个地址有关的项均已完成重定位,地址变换通常是在装入时一次完成的,以后不再改变,故成为静态重定位。

优点:无需硬件支持

缺点:1)程序重定位之后就不能在内存中搬动了;2)要求程序的存储空间是连续的,不能把程序放在若干个不连续的区域中。

动态地址重定位:不是在程序执行之前而是在程序执行过程中进行地址重定位。更确切的说,是在每次访问内存单元前才进行地址变换。动态重定位可使装配模块不加任何修改而装入内存,但是它需要硬件一定位寄存器的支持。

优点:1)目标模块装入内存时无需任何修改,因而装入之后再搬迁也不会影响其正确执行,这对于存储器紧缩、解决碎片问题是极其有利的;2)一个程序由若干个相对独立的目标模块组成时,每个目标模块各装入一个存储区域,这些存储区域可以不是顺序相邻的,只要各个模块有自己对应的定位寄存器就行。

缺点:需要硬件支持。

程序的链接与装入过程相关推荐

  1. Linux下C/C++程序编译链接加载过程中的常见问题及解决方法

    Linux下C/C++程序编译链接加载过程中的常见问题及解决方法 1 头文件包含的问题 报错信息 该错误通常发生在编译时,常见报错信息如下: run.cpp:2:10: fatal error: dl ...

  2. mysql实现程序的动态链接_程序的链接和装入及Linux下动态链接的实现

    链接器和装入器的基本工作原理 一个程序要想在内存中运行,除了编译之外还要经过链接和装入这两个步骤.从程序员的角度来看,引入这两个步骤带来的好处就是可以直接在程序中使用printf和errno这种有意义 ...

  3. C++程序编译-链接-加载过程初探-符号表

    文章目录 前言 符号表 nm指令 看一下hello world 变量和函数在符号表中的位置 看看类的定义 把类和主程序一起打包测试 符号表角度看编译与链接 加载程序到内存 前言 从自己接触计算机程序设 ...

  4. 操作系统:程序的编译、链接、装入及地址转换

    目录 静态编译与动态编译 程序链接 装入时动态链接 运行时动态链接 程序装入 静态地址重定位 动态地址重地位 基本分页存储管理的地址变换 逻辑地址空间与物理地址空间 前言 在多道程序环境下,要使程序运 ...

  5. *44.程序的链接方式

    将程序的链接方式之前,我们先理清楚程序为什么需要链接? 首先先讲一下在多道程序环境下,程序是并发运行的,程序的运行会创建一个进程,创建进程的第一件事就是把程序的数据和代码装入内存. 那么怎么把代码和数 ...

  6. 零基础学习PHP编程——程序的编写和运行过程

    零基础学习PHP编程--程序的编写和运行过程 注意: 本文主要写给零基础的同学,作为编程的入门引导, 如有不当之处,还请指正. 访问源站 欢迎交流QQ群: 640765823 回顾上一节,我们已经基本 ...

  7. C++ —— C++程序编译的四个过程

    C++ -- C++程序编译的四个过程 g++是Linux下C++的编译器:我为什么会选择Linux下的g++编译器,就是因为g++可以看到程序从编译到运行的过程做了些什么.而VS等集成开发环境看不到 ...

  8. 应用程序如何链接静态QT Plugin库

    错误描述 静态编译了QT库后,我的应用程序要链接到这些静态库.但是出现了如图所示错误: 运行时错误错误提示: This application failed to start because it c ...

  9. 计算机系统实验六:程序的链接

    参考教材:计算机系统基础 第二版 袁春风 机械工业出版社 参考慕课:计算机系统基础(四):编程与调试实践 https://www.icourse163.org/learn/NJU-1449521162 ...

最新文章

  1. JAVA 线上故障排查套路,从 CPU、磁盘、内存、网络到GC 一条龙!
  2. asp.net core中IHttpContextAccessor和HttpContextAccessor的妙用
  3. Asp.Net Core异常处理整理
  4. 二维数组最大关联子数组
  5. LA 4127 - The Sky is the Limit (离散化 扫描线 几何模板)
  6. PHPCMS v9里面,推荐位ID【posid】的值是如何确定的?是自定义的还是官方定义好的?...
  7. onmounted vue3_Vue2和Vue3使用层面上的区别总结
  8. vc 环境下mysql_windows-VC++6.0环境下C++链接MySQL数据库
  9. 怎样把照片中的头像扶正_一个男人的微信头像,往往暴露了“人品”,你是哪一种?...
  10. 分享Silverlight/WPF/Windows Phone一周学习导读(11月6日-11月12日)
  11. centos6.9安装虚拟机kvm
  12. WSL:vi 的使用、只读下的修改操作
  13. 【转】echarts x轴标签文字过多导致显示不全
  14. GCD and LCM HDU 4497 数论
  15. 《鸟哥的Linux私房菜》第四版导学
  16. Wallpaper Engine软件——html做为壁纸
  17. ZeNmap端口扫描工具详解10种扫描方式附使用脚本扫描教程
  18. java毕业生设计医疗机构药房管理系统软件开发计算机源码+系统+mysql+调试部署+lw
  19. 微信小程序设置字体加粗
  20. 从欧盟与韩国实践看智慧城市的开放式治理创新模式

热门文章

  1. datepick二格式 化时间_bootstrap datetimepicker日期插件超详细使用方法介绍
  2. php图片本地化,PHP_php将远程图片保存到本地服务器的实现代码,php如何将远程图片本地化,本 - phpStudy...
  3. 【金阳光测试】Android自动化测试第一季第三讲—Monkey原理初步和改良优化
  4. ubuntu 10.04 联想G450 安装无线网卡驱动
  5. 生命游戏Java实现
  6. 海尔转型启示录:制造业细分市场大有可为
  7. 黑龙江省人力资源和社会保障网上服务大厅 - https://www.renshenet.org.cn/sionline/loginControler
  8. mysql 数据库设计规范_MySQL 数据库设计初步规范V1.0
  9. Mapbar地图切片的抓取和拼接算法
  10. python3换行输出_python怎么输出换行