首页/操作系统/操作系统概述/程序的链接与装入 🔗 在 Obsidian 中打开
操作系统 · 操作系统概述

程序的链接与装入

重要度 ★★★★ 链接装入地址重定位动态链接
速查
程序生命周期:源代码 → 编译 → 汇编 → 链接 → 装入 → 执行。链接解决"在哪里"(符号解析 + 重定位);装入解决"地址是多少"(逻辑地址 → 物理地址)。物理地址 = 逻辑地址 + 重定位寄存器

基本概念

程序从源代码到在内存中执行,需要经过编译、链接、装入三个阶段。

链接(Linking)

将编译/汇编产生的多个可重定位目标文件合并为一个可执行目标文件,主要完成两个任务:

  • 符号解析:将符号引用(函数名、变量名)与符号定义关联
  • 重定位:将符号定义与内存地址关联,修改所有对符号的引用

装入(Loading)

将可执行文件从磁盘加载到内存,并建立进程映像。

装入方式

方式地址转换时机特点
绝对装入编译时程序必须装入指定地址,不灵活
可重定位装入(静态重定位)装入时装入时一次性转换,装入后不能移动
动态运行时装入(动态重定位)执行时运行时通过重定位寄存器动态转换,支持程序移动
绝对装入 重定位:编译时 装入后不可移动 静态重定位 重定位:装入时 装入后不可移动 动态重定位 重定位:执行时 用重定位寄存器·可移动
点击上方按钮查看三种装入方式的重定位时机
关键点动态运行时装入通过重定位寄存器(基址寄存器)实现地址转换,是虚拟内存的基础;只有它支持程序在内存中移动。

地址类型

地址类型说明
逻辑地址(虚拟地址)程序中使用的地址,从 0 开始
物理地址内存中的实际地址
逻辑地址空间程序员看到的地址空间
物理地址空间实际内存的地址空间
公式物理地址 = 逻辑地址 + 重定位寄存器值(基址)。逻辑地址从 0 开始,由 OS 和硬件转换为物理地址。

易错点

必记
  1. 链接 $\neq$ 装入:链接是合并目标文件,装入是加载到内存。
  2. 静态重定位 $\neq$ 静态链接:静态链接是链接方式,静态重定位是装入方式。
  3. 动态重定位需要硬件支持:重定位寄存器(基址寄存器)。
  4. 共享库用动态链接:静态链接会复制库代码,浪费内存。
  5. 逻辑地址从 0 开始:实际物理地址由 OS 和硬件转换。

记忆卡片

链接的两个主要任务?
符号解析和重定位。
三种链接方式?
静态链接、装入时动态链接、运行时动态链接。
三种装入方式?
绝对装入、静态重定位、动态重定位。
哪种装入支持程序移动?
动态运行时装入(动态重定位)。
动态重定位需什么硬件?
重定位寄存器(基址寄存器)。
物理地址 = ?
逻辑地址 + 重定位寄存器值。

交互动画 · 静态链接 vs 动态链接:从目标文件到内存

手动模式
main.o可重定位目标文件 util.o用户自写函数 libc.a 静态库库代码副本 libc.so 共享库独立于程序 链接器符号解析+重定位 静态可执行文件内含库代码(大) 动态可执行文件仅记录符号引用(小) 共享库实例(内存) 内存(物理地址)
静态链接:运行前合并为一个文件 ──┬── 动态链接:libc.so 运行时才装入
点击「播放」或「下一步」,看目标文件如何链接、装入、重定位
物理地址 = 逻辑地址 + 重定位寄存器(基址)
变量配色:目标文件/静态链接 · 动态库/运行时链接 · 内存装入

相关知识点

interrupt-and-exception system-call

↑ 以上为站内 HTML 相对链接(纯网页可浏览);本页右上「在 Obsidian 中打开」跳回源笔记。