如何让内存使用起来?
将程序放入内存中,不断取出指令,CPU执行指令(即能让程序执行起来)。
如何让程序装入内存?
1.绝对装入方式
2.可重定位装入方式
3.动态运行时装入方式
那么首先让程序进入内存
如果是这样不经处理直接装入内存,那么main函数的第一条指令就应该放在物理内存地址40这个地方,否则没法执行。
但是万一有其它程序放在这里,那么就不行了,所以实际上应该是找一块空闲内存来放这个程序。
但是又有问题了,IP=1000取指执行,call 40,IP=40,就会跳到下面去执行,然而我们希望执行的main函数的第一条指令的地址是在1040。
所以call 40,40是逻辑地址,程序中的地址,是相对地址,是编译程序时写成的地址。将程序装入内存时,将逻辑地址修改为物理地址。
call 40 -> call 1040
这样就引入了重定位。在装入时对程序中指令和数据的修改过程称为重定位。
什么时候完成重定位?
1.编译时
2.载入时(更灵活)
编译时重定位的程序只能放在内存固定位置;
载入时重定位的程序一旦载入内存就不能动了
但是…..
程序载入后还需要移动
多道程序环境下,内存中的某些进程可能被阻塞,但却占用大量内存空间,而又有许多进程在外等待,因没有内存而不能进入,这对系统资源造成浪费。
交换是将内存中暂时不能运行的进程或者暂时不用的程序和数据调出到外存。
进程1在载入的时候为1040,换出后在换进来还是1040,但是此时进程1已经放到了2000的位置,如果此时取指执行call 1040,就跑到其他地方去了。所以只在载入时重定位其实并不能满足要求。
重定位最合适的时机
运行时重定位
基地址放在进程PCB里面。在前面那张图中,换出去之前进程1PCB里面的base是1000,换出去再换进来,进程1的base是2000。执行指令时第一步是从PCB中取出这个基址。
总结
拿到一个可执行程序,要使用内存,就是让可执行程序执行起来。首先找到一段空闲内存,找到空闲内存的初始地址,赋给进程的PCB里面,程序载入到这段空闲内存中。在上下文切换时,PCB里面的基址就变成基址寄存器,每取指执行时,在执行过程中都要进行地址翻译,一翻译就找到这条指令实际使用的物理内存地址。
每次执行指令时都要从PCB中取出base基址(其实这个基址放在了基址寄存器里面)