操作系统系列学习——内存使用与分段


前言

一个本硕双非的小菜鸡,备战24年秋招,计划学习操作系统并完成6.0S81,加油!
本文总结自B站【哈工大】操作系统 李治军(全32讲)
老师课程讲的非常好,感谢
【哈工大】操作系统 李治军(全32讲)

内存使用与分段

在这里插入图片描述
程序需要放在内存中,程序需要在内存中取。取值执行程序,内存也就跟着使用了。

内存使用方法:将程序放入内存中,并让程序执行起来
在这里插入图片描述
如何把程序放入内存中并执行?
用磁盘将程序读到内存中
要想程序正常执行(这段例程),根据call40就必须要求main也要放在真实物理地址40处。程序要从0地址开始,一句一句放进去,然后pc=0开始取值执行。但有个问题:0地址并不是可供一个程序使用。

正确方法:应该是在内存中找一段空闲的内存,然后将这段程序放在这段空闲内存中。
在这里插入图片描述
解决:使用逻辑地址。修改程序中的内存地址的操作叫做重定位

什么时候完成重定位?

**1.编译时:**对于嵌入式系统可以在编译时完成重定位,但不灵活;

**2.载入时:**程序加载到内存的时候,比较灵活(非嵌入式系统一般都采用载入时进行重定位); 如程序从磁盘载入到内存时,程序中的内存地址(地址偏移量)统统加上程序所在基址;

重定位优缺点:

编译时重定位的程序只能放在内存固定位置(死板,编译时需要确定存放程序的空闲内存的基址);

载入时重定位的程序一旦载入内存就不能动了(灵活,载入时才确定存放程序的空闲内存的基址);

在这里插入图片描述
进程阻塞长时间不用,不能让他一直占用内存。使用交换机制

在这里插入图片描述
那么首先让一个程序编译好了,这个时候程序里面的都地址不需要修改,然后接下来让他执行需要创建进程(pcb)。那么需要在内存中找一段空闲的内存,然后把这个这段空闲的起始地址(基地址)找到并赋给PCB。然后把这段程序放到这一段空闲内存中,然后接下来在上下文切换的时候,基址就变成了基址寄存器,然后每执行一条指令的时候进行取值都要执行地址翻译(就是要取出一条地址,再拿PCB中的基址(基址寄存器中))那么一翻译就找到了你这条指令实际使用的物理内存的地址。
在这里插入图片描述
程序分段对于存储的好处(分段存储采用的是分治思想)

好处1:不是将整个程序放入内存,而是将各段分别放入内存,提高内存利用率;
好处2:在做swap时,不是把整个进程换入或换出,而是把进程的某个段换入或换出,提高了swap效率;且减少了swap次数;
好处3: 程序段或代码段是只读的;(变量集)数据段是可写的;分段存储可以避免代码被误写的场景;

在这里插入图片描述
每个进程也有自己的段表(用于存储程序多个段的基址)LDT表

可以把操作系统看作一个进程,操作系统对应的段表就是GDT表

进程一对应的段表就是LDT表

在这里插入图片描述
操作系统这个表放在gtd表里面,然后每个进程有自己的ldt表。那么在进程切换的时候ldt跟着切换,则在每次进行地址翻译的时候,根据ldt表里面来对应的基址、数据段和代码段找到程序中那个逻辑地址,所以完成了重定位过程就到物理地址可以去真正执行这条指令

在程序分段情况下使用内存的步骤;

步骤1:把程序分为多个段,包括代码段,数据段等;

步骤2:每个段在内存中找到一块空闲内存,并把这一段内存基址(起始地址)送入LDT表存储(如表1结构);LDT表就存储了该程序多个段的段基址;

步骤3:把LDT表赋值给对应进程的PCB; 至此程序已经被载入到内存中了;

最后:PC寄存器根据pcb设置初值,取指执行取指执行,在每执行一条指令的时候, 都查询LDT表找到段基址,并把该段基址加上地址偏移量得到物理内存地址,以进行后续的寻址操作;

补充: ldt表基址送入ldtr寄存器;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

努力找工作的小菜鸡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值