4.2 程序的装入和链接

L23

学习目标

页表、地址变换;段表与段的逻辑意义。为第五章虚存打基础。

  • 页是物理管理单位,段是逻辑单位。
  • 无 MMU 的 MCU 用「编译期分区」近似。
  • 对换区、换出进程。
  • 本课不实现 swapping。
  • 虚存是 OS+硬件协同。
  • 本课以原理+动画为主,不在 C5 教学内核实现完整请求页。
  • 内部/外部碎片。
  • 首次适应等分配策略。

原理 · 深入理解

4.2 程序的装入和链接

用户程序运行前须经编译、链接、装入三步,将源程序转为可执行内存映像。

  1. 编译:编译程序将源程序编译成目标模块
  2. 链接:链接程序将目标模块与库函数链接成装入模块
  3. 装入:装入程序将装入模块装入内存
图4-2 对用户程序的处理步骤 编译 链接 装入 运行
图4-2 对用户程序的处理步骤

4.2.1 程序的装入

单道程序环境下可预知程序驻留位置,采用绝对装入:编译产生绝对地址目标代码。

程序使用符号地址,编译或汇编时转为绝对地址;也可由程序员直接赋予。

  1. 三种装入方式:绝对装入、可重定位装入、动态运行时装入

可重定位装入允许装入到任意允许位置,但不允许运行时在内存中移动。

动态运行时装入把地址转换推迟到程序真正执行时才进行,便于程序运行中移动位置。

图4-3 作业装入内存时的情况 高地址 OS 作业 A 空闲 低地址
图4-3 作业装入内存时的情况

多道环境下编译程序无法预知目标模块在内存位置,绝对装入不再适用。

目标模块起始地址通常从0开始,其它地址相对起始计算,应按内存情况装入到适当位置。

4.2.2 程序的链接

静态链接在运行前将各目标模块及库函数链接成完整装配模块,以后不再拆开。

  1. 对相对地址进行修改
  2. 变换外部调用符号

须解决两个问题:修改相对地址、变换外部调用符号。

图4-4 程序链接示意图 目标模块 链接 装入模块
图4-4 程序链接示意图

装入时动态链接(Load-time Dynamic Linking)

装入时动态链接指将用户源程序编译后所得到的一组目标模块,在装入内存时,采用边装入边链接的链接方式。即在装入一个目标模块时,若发生一个外部模块调用事件,将引起装入程序去找出相应的外部目标模块,并将它装入内存,还要按照图4-4所示的方式修改目标模块中的相对地址。 装入时动态链接方式有以下优点。

  1. 便于修改和更新
  2. 便于实现对目标模块的共享
图4-4 程序链接示意图 目标模块 链接 装入模块
图4-4 程序链接示意图

运行时动态链接(Run-time Dynamic Linking)

低效→在许多情况下,应用程序在运行时,每次要运行的模块可能是不相同的。但由于事先无法知道本次要运行哪些模块,故只能是将所有可能要运行到的模块全部都装入内存,并在装入时全部链接在一起。

运行时动态链接方式: 将对某些模块的链接推迟到程序执行时才进行,在执行过程中,当发现一个被调用模块尚未装入内存时,立即由OS去找到该模块,并将之装入内存,将其链接到调用者模块上。凡在执行过程中未被用到的目标模块,都不会被调入内存和被链接到装入模块上。

做 · 实验

  • 根据「学习目标」列出 3 个关键词,对照原理段落解释给自己听。
  • 完成 06-heap 或等价练习:分配-释放-再分配观察。

打开工作台

程序的装入和链接

swapping

用控件单步操作;日志区记下每一步发生了什么。

代码导读

本课在工作台编译烧录。先读 user 实验入口,再对照 kernel / HDF 中被调用的函数,不要一上来改链接脚本。

总结与提升

  • 能对比页式与段式的优缺点各一条。
  • 能用自己的话复述学习目标,并指出概念与板上实验的对应。
  • 能说明 MCU 课为何跳过对换实验。
  • 能说出虚存依赖的硬件支持。
  • 能区分内碎片与外碎片。
  • 能结合动画解释一次分配失败原因。
  • 能说出 Flash 与 DRAM 在链接中的角色。

延伸思考

  • ESP32 的 MMU/Cache 与教材页表哪一层接近?
  • 如果把本节机制拿到 Linux 或完整 OpenHarmony 上,会多出哪些硬件假设?
  • 把进程映像存到 Flash 文件系统算对换吗?
  • 没有缺页中断能否做虚存?

← 本阶段封面 · 课程列表