10 内存使用与分段

——>如何让内存用起来?

我们知道CPU的工作过程是取指执行,取指令就是在内存中的相应位置取指令,因此CPU和内存是同步工作的。如下图所示

程序原本存放在磁盘中,要使用时先加载进内存,那么程序就要在内存中找块地址放进去

原本程序在磁盘中存在0位置,main函数存在40位置,直观的做法就是,把程序地址原封不动读入内存的相应位置,那么问题来了,下次载入其他程序时,也有可能使用0和40位置,况且内存的0位置存的是操作系统的初始位置,这样显然行不通,那么行的通的办法时,在内存中找一块空闲的地址放入程序,起始位置作为基地址,程序中的物理地址为基地址+磁盘中的逻辑地址
 

将程序在磁盘中的地址修改为内存中地址的操作叫作重定位

那么应该在什么时候完成重定位呢

  1.    编译时:但编译时很难知道内存中哪些位置是空闲的,重定位的程序只能存放在内存固定位置,适用於单片机这种静态的嵌入式系统
  2. 载入时:载入时重定位的程序一旦载入内存就不能动了

常用的计算机程序载入后还需要移动的
  比如某个进程长时间阻塞,就应该把它换出,释放出内存让给其他进程,这样才能充分利用内存,并且内存的大小是有限的,如果运行的进程比较多,就必须要支持换入换出操作,如下图所示

由于进程存在换入换出操作,那么进程(运行的程序)在内存的存放地址就会发生改变,因此程序合理的重定位时机应该在运行时重定位

每执行一条指令都要从逻辑地址算出物理地址:地址翻译

执行指令时第一步是从PCB中取出基地址,物理地址=基地址+逻辑地址

那么执行指令的过程如下图所示

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>分割线>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

引入分段:程序载入内存时是将整个程序载入一段连续的内存吗?

程序员眼中的程序:由若干分段组成,每个段有各自的特点、用途->代码段只读,代码段/数据段不会动态增长,但是堆栈段空间会动态变化

将静态的短和动态的段放在一起容易引起互相干扰,并且若整个程序连续存储,那么堆栈段变化时,整段程序都要移动(类似数组的插入删除),如果分段存储,堆栈段动态变化时只会引起堆栈段的内存变化。

所以,程序应该在内存中分段存储,那么每次计算指令的物理地址时就要根据不同的段基址计算,而不是整个程序只有一个基址,如下图所示

程序中每段的基址存在进程表中,进程表又保存在PCB中,因此进程切换时,进程表也会切换,进程表(LDT)类
似操作系统启动时的GDT(全局描述表),LDT又叫局部描述表它们的关系如下图所示

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章