(计算机组成原理基础回忆)1)存储单元大小
- 如果是【按字节编址】:就是一个存储单元大小是【1字节】=【8位(8 bit)】
- 如果是【按字编址】:就是一个存储单元大小是【1个字】=【具体一个字多大取决不同的计算机(比如下图例子:一个字16位)】
2)存储单位换算
- 【计算机组成原理】和【操作系统】的关于【存储】的单位换算都是按:
- 【2的10次方】、【2的20次方】、【2的30次方】来换算
- 【计算机网络】的关于【速度】的单位换算都是按:
- 【10的3次方】、【10的6次方】、【10的9次方】来换算
一、【装入】和【链接】(理解即可)
1、【程序装入】基本概念
人话:就是各个进程运行时,他们的数据都是从外存放到内存的,因为进程的独立性,他们的数据需要装入到内存里各自不同的地方
基本过程分为3步:
1)【编译】
- 人话:把程序员写好的代码、数据,"翻译成" 计算机看得懂的语言文件
- 其中计算机组成原理里讲过【编译过程】,可以回顾一下(预处理、编译、汇编)
2)【链接】
人话:把刚刚编译的几个分离的文件,合成一整块【模块】(类比快递打包)
3)【装入】
- 人话:把这【模块】通过【装入程序】放到内存空闲区域,就可以供进程运行使用
【整个过程总结】:
2、【逻辑地址】和【物理地址】概念
前面我们已经了解了一个进程所需要的代码、数据是怎么装入到内存的一整个过程,现在我们的重点是研究:
- 【进程所需的这些数据、代码】应该【放到内存什么位置?】
- 【进程】去内存【取数据、代码】的时候怎么知道他要的数据、代码**【到底在内存哪里?】**
- 【逻辑地址】:
- 进程还未存入内存的实际地址前,它所需的数据要存放在**【自己的进程装入模块哪个位置】**
- 【实际地址】:
- 进程所需数据模块已经存到内存了,进程去**【内存里实际要找到的地址】**
逻辑地址就像:你的大衣挂在自己宿舍储物柜里的下层,睡衣内衣和杂物放在储物柜上层;实际地址就像:你的大衣实际在6栋宿舍302里靠阳台的3号柜子里的下层。
3、三种装入策略

1)静态绝对装入
人话:提前定死了【逻辑地址】=【实际地址】
2)重定位装入(逻辑地址≠实际地址,二者有映射关系)
这里注意区分【静态重定位】和【动态重定位】的重点:
- 【静态重定位】:
- 【逻辑地址 转化成 实际地址】发生的时机是在**【装入内存时(即程序运行之前)】**完成
- 【动态重定位】:
- 【逻辑地址 转化成 实际地址】发生的时机是在**【程序动态运行时】动态进行**
【静态地址重定位】(又叫【可重入定位】)
重点:【逻辑地址 转化成 实际地址】只能在**【装入内存时(即程序运行之前)】**完成,只有这么一次转换,后续不再变
- 【关于 "进程对换、移动" 的概念】
- 由于进程挂起、进程终止等原因,进程不会一直呆在内存
- 而【可重入定位】中,进程的地址在装入时已经一次性定死了,一旦它发生对换后,内存里个地址空间一旦发生变化,他原先的地址就作废了,当它【调出 ---> 再调入】后就不能再进内存了
因此说**【没有对换功能的内存管理方式】可以用【静待地址重定位】**
【动态地址重定位】
重点:【逻辑地址 转化成 实际地址】可以在**【程序动态运行时】动态进行**
注意,这里涉及到【2个硬件】和【1个软件】:
- 【硬件】:【重定位寄存器】、【地址变换机构】
- 那么**【物理地址】=【逻辑地址】+【重定位寄存器值】**
- 【软件】:【可重定位装入程序】
这里涉及到一个【内存紧缩】知识点,先简单提一下:
- 当进程从内存和外存之间移出移进的过程中,内存会留出很多间隙,也叫【空洞】
- 如果不让进程紧挨着留出空位的话,虽然有很多空闲地方,因为这些空闲空间不是连续的,就没办法给新进程装入。
- 因此通过【内存紧缩】技术,可以让各个进程在内存中移动、靠近,从而留出大量【连续的空闲空间】来给新进程装入
- 而进程移动也必然会导致【实际地址改变】,因此需要依靠【动态地址重定位】,让程序在运行中也能够随时变换地址空间
(就像吃席,坐的间距太大就不够很多人坐得下,要大家靠近一点才有空位给新人坐进来)
【总结】
【例题】
4、三种链接策略
【静态链接】
【装入时动态链接】
【运行时动态链接】
【例题】
【分段后面会学到,先记着】
分段就是把进程分成【空间大小各不一样】的段,每个段有不同的功能和权限
有时候一个程序里总有一些代码暂时用不上,就可以通过分段识别是哪些段暂时不用,先不链接,等要用时再动态链接到内存
二、内存保护

1、设置【上限寄存器】、【下限寄存器】
属于:静态重定位 + 内存保护
- 存放内容:物理地址(实际内存地址)
- 下限寄存器(基址寄存器) :进程起始物理地址
- 上限寄存器 :进程结束物理地址
- 工作方式(静态): 程序装入内存时就确定好物理实际位置,运行中地址不再改变。 CPU取逻辑地址后:【物理起始地址 = 逻辑地址 + 下限寄存器(基址寄存器))
2、设置【重定位寄存器】、【界地址寄存器】
属于:动态重定位 + 内存保护
- 存放内容:实际物理地址 + 逻辑地址
- 重定位寄存器(基址寄存器) :存放进程当前所在内存的起始物理地址
- 界限寄存器 :存放进程的逻辑地址空间大小(最大逻辑地址)
工作方式(动态重定位流程):
- 程序内部用逻辑地址运行(编译 / 链接出来的地址不变)
- 运行时动态计算物理地址:【物理起始地址 = 逻辑地址 + 重定位寄存器(基址寄存器)】
- 越界检查:逻辑地址 < 界限寄存器值,否则报错。
【例题】
三、进程的内存映像
前面学进程时学过,进程映像就是进程运行过程中的一个【快照】,粗略的理解是【PCS + 代码段 + 程序段】
但是实际上我们要研究【进程在内存中的映像 】,也就是**【一个进程运行时在内存里会存储、用到哪些数据/代码】**
特别注意:
- 1、注意【scanf】和【printf】函数是【输入、输出】函数,会触发【I/O中断】
- 另外注意:【触发I/O中断时(阻塞态)】和【执行I/O时(运行态)】两个时机的区别
- 2、区分【指针变量】、【"指针变量"所指向的 "实际数据"】和【malloc函数本身】的区别
- 【指针变量】:如果是函数外全局变量就是【可读写数据】、如果是函数内局部变量就是【数据栈段(用户栈段)】
- 【"指针变量"所指向的 "实际数据"】:是真正存放于malloc函数帮他们分配的空间,也就是【数据堆段】
- 【malloc函数本身】:只是一个库函数,在【共享库映射区】
【例题】
1、这个例题在2.1进程章节的课后题第22题做过,各位可以回去看看











逻辑地址就像:你的大衣挂在自己宿舍储物柜里的下层,睡衣内衣和杂物放在储物柜上层;实际地址就像:你的大衣实际在6栋宿舍302里靠阳台的3号柜子里的下层。



因此说**【没有对换功能的内存管理方式】可以用【静待地址重定位】**


(就像吃席,坐的间距太大就不够很多人坐得下,要大家靠近一点才有空位给新人坐进来)
































