内存使用于分段
一.使用内存
从磁盘里读入到内存中,从0地址开始依次存放程序,pc从0开始取值执行,mian的第一条指令放到内存地址40的地方,0地址可以随便用吗?0地址一定有空间吗?,其他程序应该放在哪呢?
0地址是放操作系统的,所以程序不能放在0地址, 应该找一段空闲的内存地址,将程序放进来,将逻辑地址40修改成物理地址
二.重定位
编译时修改程序中的地址:编译的时候加上基址,还需要知道哪个内存是空闲的,实际的系统中无法知道,编译的时候是空闲的,执行的时候有可能之前空的内存已经被别人占用了,所以需要保证地址一定是空闲的,适合静态系统或嵌入式
载入时修改程序中的地址:假设载入一条指令的时候发现1000是空闲的所有地址都加上1000,根据当前内存那个是空闲的内存,找到基址,载入的时候程序的所有地址全都加上找到空闲内存的基址,载入到1000之后就不能修改了
进程1阻塞将进程1放进磁盘,将进程2放进内存,交换之后不能保证地址是否为空的
运行时重定位:每次都根据基地址和偏移地址来修改,进程变化的信息都放在PCB中,base放到PCB中,执行进程的过程中一直有PCB,PCB里一直有基址
总结一下:在内存中找一个空闲的内存,找到内存的基地址,将地址作为base赋给PCB,因为需要上下文切换,需要将当前TCB的基地址,放到基址寄存器中, switch()的时候将基址寄存器的存放的地址,写回到原来的TCB中,再将新切换的进程的基地址,放入到基址寄存器中,执行指令的时候根据基地址和偏移地址,形成物理地址
三.分段
程序不是全部都放到内存中,每个段内的程序都是从0开始的,如果不分段。当某个空间不够时需要重新申请一块空的内存将这些内容放到新的空间中,寻址方式变成<段号,段内偏移>
操作系统的表放在GDT表中,每个进程有自己的LDT表,在进程切换的时候,LDT表也跟着切换,LDT切换了以后,在每次进行地址翻译的时候,根据LDT表中的基址,就找到当前程序中逻辑地址的物理地址,就完成了重定位过程,就可以到物理地址上可以真正执行这条指令真正去取指令,内存就使用起来了
总结:一个程序分成多个段,每个段从内存中找到一个空闲的地方,将每个段的基地址放到LDT表中,分别将程序放到各个段中,这样一个程序就载入到内存中了,将LDT表赋给TCB,IP设置初始地址,根据IP指针取值执行,在每执行一条指令的时候都查这个表,找到程序中的哪些地址,根据基址和程序中的地址,找到物理地址,找到这个为物理内存,就可以执行响应的操作