Appearance
程序的链接与装入
考情分析
三种装入方式和三种链接方式是选择题考点,特别是与地址重定位的结合。🔥🔥 中频。
写完代码点了"运行",程序就跑起来了——但编译器生成的地址是从 0 开始的,内存里凭什么知道这些地址该放在哪?
程序从源码到运行的过程
三种链接方式
| 方式 | 时机 | 说明 |
|---|---|---|
| 静态链接 | 运行前 | 所有目标模块和库在装入前就链接成一个完整的可执行文件(类似出发前把所有行李打包成一个大箱子) |
| 装入时动态链接 | 装入内存时 | 边装入边链接,便于模块更新 |
| 运行时动态链接 | 运行时 | 需要某个模块时才去链接(如 .dll / .so),最节省内存 |
静态链接 vs 动态链接
| 比较 | 静态链接 | 动态链接 |
|---|---|---|
| 可执行文件大小 | 大(包含所有库代码) | 小(只包含引用) |
| 内存使用 | 库代码可能重复加载 | 多进程可共享同一份库 |
| 更新维护 | 需要重新编译链接 | 替换 .dll/.so 即可 |
三种装入方式
1. 绝对装入
| 项目 | 说明 |
|---|---|
| 适用 | 单道程序环境 |
| 地址 | 编译时就确定了物理地址 |
| 限制 | 程序只能装入固定位置 |
2. 可重定位装入(静态重定位)
| 项目 | 说明 |
|---|---|
| 适用 | 早期多道程序系统 |
| 地址转换 | 装入时一次性将逻辑地址转换为物理地址 |
| 限制 | 装入后不能再移动(地址已写死) |
3. 动态运行时装入(动态重定位)
| 项目 | 说明 |
|---|---|
| 适用 | 现代操作系统 |
| 地址转换 | 运行时通过重定位寄存器(基址寄存器) 进行地址转换 |
| 优势 | 程序可以在内存中移动,支持虚拟内存 |
物理地址 = 基址寄存器值 + 逻辑地址三种方式的对比
| 比较 | 绝对装入 | 静态重定位 | 动态重定位 |
|---|---|---|---|
| 地址转换时机 | 编译时 | 装入时 | 运行时 |
| 装入后可移动 | 否 | 否 | 是 |
| 需要硬件支持 | 无 | 无 | 重定位寄存器 |
| 适用系统 | 单道 | 早期多道 | 现代 OS |
考研高频考点
- 🔥🔥🔥 三种装入方式的区别(特别是静态重定位 vs 动态重定位)
- 🔥🔥 动态重定位需要重定位寄存器,装入后可移动
- 🔥🔥 静态链接 vs 动态链接的区别
- 🔥 运行时动态链接最节省内存(共享库)
程序装入内存后,它在内存中是什么样的布局?代码段、数据段、堆、栈分别在哪里?下一篇来看进程的运行时内存映像。