第四章 存储器管理 4.2 程序的装入和链接
在多道程序环境下,程序要运行必须为之创建进程,而创建进程的第一件事情就是要把用户编写好的源程序和数据装入内存。如何将一个用户源程序变为一个可在内存中执行的程序,通常要经过下列几步:
1.编译
源程序模块是用高级语言或汇编语言写的一组程序语句。由编译程序对用户源程序进行编译,形成若干个目标模块(.o)
2.链接
目标模块是纯二进制的机器级代码。一组目标模块以及它们所需要的库函数被链接程序链接在一起,形成一个完整的装入模块
3.装入
由装入程序将装入模块装入内存并执行
一、程序的装入
根据存储空间的分配方式,将一个装入模块装入内存时,可采用三种方式:
1.绝对装入方式
程序中的逻辑地址与实际内存地址完全相同,装入时不需对程序和数据的地址进行修改。 (程序员事先知道程序将驻留在内存的什么位置)
2.可重定位装入方式
目标模块中为相对地址(通常从0开始),即地址都是相对于0开始的。 装入模块中的逻辑地址与实际装入内存的物理地址不同。
重定位:装入内存时,相对地址(数据、指令地址)要作出相应的修改以得到正确的物理地址
①静态重定位
地址变换是在装入内存时一次完成的,且以后不能移动
一般情况下,物理地址=相对地址+内存中的起始地址
一个程序通常需要占用连续的内存空间,程序装入内存后不能移动,不易实现共享
②动态重定位(动态运行时装入方式)
3.动态运行时装入方式
装入程序将装入模块装入内存后,并不立即把装入模块中的相对地址转换为绝对地址,而是把这种地址转换推迟到程序执行时进行。
将有效地址与重定位寄存器(RR)中的内容相加后得到的地址作为访问主存的地址。
程序中所有指令和数据的实际地址是在运行过程中最后访问的时刻确定的。
二、程序的链接
经过编译后所得到的一组目标模块以及它们所需要的库函数,装配成一个完整的装入模块。
根据链接时间的不同,可把链接分成三种:
1.静态链接
在程序运行之前,先将各目标模块及它们所需的库函数,链接成一个完整的装入模块,以后不再拆开。
需解决以下两个问题:将相对地址进行修改;变换外部调用符号。
这种先进行链接所形成的一个完整的装入模块,又称为可执行文件。
2.装入时动态链接
目标模块是在装入内存时,边装入边链接的。即在装入一个目标模块时,若发生一个外部模块调用,将引起装入程序去找出相应的外部目标模块,并将其装入内存。
(事先无法知道本次要运行哪些模块,只能将所有可能要运行的模块在装入时全部链接在一起,而实际上往往有些目标模块根本不会运行)
3.运行时动态链接
将某些目标模块的链接推迟到执行时才进行,不构造完整的目标模块。即在执行过程中,若发现一个被调用模块尚未装入内存时,由OS去找到该模块,将它装入内存,并链接到调用模块上。
执行过程中未被用到的目标模块,都不会被调入内存和被链接到装入模块上,不仅可加快程序的装入过程,而且可节省大量的内存空间
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!