物理内存和虚拟存储空间
1.物理内存
1.1 物理内存是由系统实际提供的硬件存储单元(字节)组成的,CPU可以直接访问这些存储单元,所有的指令和程序必须装入内存才能执行;
1,.2 内存中所有的存储单元都从0开始编号,这个编号是这个存储单元的内存地址或物理地址;比如0000 0000H
1.3 内存的地址空间是一维的,它的大小受到实际存储单元的限制,存储单元最大的内存地址加1称为内存空间大小;比如0000 0000H 到
003F FFFFH,最大地址是003F FFFF = 00000000 00111111 11111111 11111111 + 1= 000000000 01000000 00000000 00000000=2^23bit=8Mbit?
2.虚拟存储空间
用户编写的源程序变为虚拟程序的几部:
2.1.1 编译,由编译程序将用户程序的源程序编译成若干个目标模块
2.1.2 链接,由链接程序将编译后的目标模块以及他们所需要的库函数链接在一起形成一个完整的可装入模块;
2.1.3 由“系统装入程序”将“装入模块”装入内存;
3.访问内存地址:
3.1 程序中直接给出要访问的数据或者指令的物理地址;
3.2 用高级语言或汇编语言进行编程时,源程序中使用的都是符号地址;源程序经过编译链接之后,形成一个以0为起始地址线性或多维的虚拟地址空间,每条指令或数据都有确定的地址在这个虚拟空间中;这个地址被称为虚拟地址或相对地址;程序运行时访问的内存由地址装入模块的地址变换机构完成;
3.3 虚拟存储控件不考虑物理内存的大小和信息存放的时机位置,只规定每个进程中互相关联的信息的相对位置;
3.4 每个进程都有自己的虚拟存储空间;
3.5 虚存大小是由计算机的地址结构和寻址方式决定的;例如直接寻址,CPU的有效地址长度是20位,其中的寻址范围为0~220;
存储管理的主要任务
1.内存分配
分为静态分配和动态分配:
1.1 静态分配,在目标模块装入内存时,一次性分配内存所需的存储空间;不允许进程在运行过程中再申请内存空间;
1.2 动态分配,在目标模块装入内存时,分配进程所需的基本内存空间,并允许内存在运行过程中再次申请内存空间;
2.地址变换
实际上就是建立由虚拟地址(逻辑地址)到物理地址的映射;分为静态地址重定位和动态地址重定位:
2.1 静态地址重定位:
总结:相对地址+装入的起始地址
静态重定位是在程序执行之前进行重定位,它根据装配模块将要装入的内存起始位置,直接修改装配模块中的有关使用地址的指令。
栗子:一个以“0”作为参考地址的装配模块,要装入以100为起始地址的存储空间。显然,在装入之前要做某些修改,程序才能正确执行。例如,MOV EAX,[500]这条指令的意义,是把相对地址为500的存储单元内容1234装入EAX号累器。现在内容为1234的存储单元的实际地址为1500, 即为相对地址(500)加上装入的地址(1000),因此,MOV EAX,[500]这条指令中的直接地址码也要相应地加上起始地址,而成为MOV EAX,[1500]。
2.2 动态地址重定位
总结:CPU经过逻辑地址访问内存时,逻辑地址会被BR自动加上BR内的地址以便形成实际的物理地址;
程序在执行的过程中,在CPU访问内存地址之前,由地址变换机构(硬件)完成要访问的志林或数据的逻辑地址到物理地址的变换;
BR(公用的基址寄存器),存放在现行进程在内存空间的起始地址。CPU经过逻辑地址访问内存时,逻辑地址会被BR自动加上BR内的地址以便形成实际的物理地址;如果程序在内存中的位置发生了改变,只需要改变BR的内容就可以正确的访问程序;
至于好处与坏处请参阅传送门;
3.内存信息的共享和保护
3.1上下界保护法:硬件保护法,为每一个进程设置一对上下界寄存器,装有被保护程序和数据段的其实地址和终止地址;在程序执行过程中中,在对内存进行访问操作时,首先对访问地址合法性进行检查,即检查经过的重定位后的内存地址是是否在上下界寄存器规定的范围之内,在访问,不在是非法访问,产生访址越界中断;
3.2 保护键法;
该方法为每一个被保护存储块设置一个单独的保护键,保护键可以是读写同时保护,可以是读或写单个保护;
如图:2K-4K 段是读写保护,4K-6K段是读保护,6K-8K段是写保护,(保护的意思就是在这个段不能执行该操作);没学过汇编的可以认为LOAD是读内存,STORE是写内存;
这里涉及一个很关键的概念叫做程序状态字PSW,程序状态字设置相应的保护键开关字节,对不同的进程赋予不同的开关代码,与被保护的存储块中的保护键相匹配;如果开关字中的代码与保护键匹配 或 存储块未收到保护,允许访问该存储块;标黄字体的含义通俗的讲就是,我给你这段程序一个程序关键字,然后如果这个程序状态字和你访问的区域的保护字是一样的,你就可以无视保护键直接访问这块区域的任何东西,如果不一样就是访问中断出错;
上图中给定的程序状态字是2;那么load 1 5000 ;5000是对应保护键为2的区域,要对这块进行读,但是他有读保护,但是!我的程序状态字是2,和这块保护键2是匹配的,我可以无视他的读保护,直接进去读,store 2 5200 也是同理,只不过这个读保护实际上对她也没用,因为本身就不是去读的,是去写的;
然后load 2 7000 ;对应的是保护键为3的区域,尽管状态字为2与保护键3不匹配,但是他只有写保护,而我要读,所以不影响,直接就进去了;
至于load 1 2500 是访问保护键为1的区域,状态字不匹配,而且他读写保护都有,就进不去了;
store 1 7500 也是,状态字不撇皮,要写,但是有写保护,进不去;
3.3 界限寄存器与CPU的用户态或核心工作方式相结合的保护方式;用户进程只能访问哪些在界限寄存器所规定的范围之内的内存部分;
而核心态进程则可以访问整个内存空间地址;
4.内存扩充
虚拟存储技术
分区式存储管理
1.固定分区:
分区内未被使用的无效的存储空间是内碎片;
2.可变分区(重要)
在装入进程的过程中,根据进程的实际需要建立分区,该分区的大小正好等于进程的大小,随着系统的运行,内存中的分区大小,个数都会发生变化;
问题1的处理:
分配内存流程图:
使用的数据结构1.空闲分区表
2.空闲分区链
问题2的处理:
问题3的处理,情况1:选中的空闲分区本来就比给定的进程大,直接修改对应的分区表的数据就行;
情况2:进程大小==空闲分区,分配后在表中对应的表象删除
回收:情况1,回收区后又相邻的空闲分区,回收后两个相邻的空闲分区合并;
同上,但是在前;
情况3:合并前后
情况4:增加
要采用动态重定位的方式访问地址