前言
在8086/80186时还没有操作系统,把它称之为实地址模式。
那么怎么将地址表示出来呢?
比如:数据寄存器DS中的值是16位,要转换成20位的地址。怎么转换呢?
所以左移四位后则低四位变为0了,然后再加上IP寄存器中的偏移值,就是物理地址。
DS << 4 + IP (即偏移值)= 物理地址 没有操作系统则它的空间就称为物理空间(上图的空间)
DS(基地址) IP(偏移地址、偏移量、逻辑地址)
IP寄存器中最多存16位,则偏移量最多为2^16=64K.
因为起始位置必须是16的倍数,则整个段大小在16B-64K之间,则它的真实大小就不确定,就可能导致如果别人恶意修改这个IP寄存器中的值,则段的大小就会发生改变,就会导致访问无法访问的空间。
因此为了解决这样的问题,所以我们就需要保存记录 基地址 段大小 以及 访问权限 。
所以在有了操作系统以后,因为要向上兼容,所以上述寄存器不改变,而添加 GDTR(全局段描述表寄存器) 和 LDTR(局部段描述符表寄存器)。
我们这里先从GDTR分析,是在内存存储的全局段描述表(相当于数组)
GDTR存储了这些,那么DS、CS、SS(ES)这些寄存器做什么呢?
存储 段描述符表的下标 段描述符表的类别 以及权限位
当操作系统启动时,默认占据12个描述符表项,而用户进程最多只能用8192-12=8180个描述符表项。
继续说当有了GTDR和LDTR后的实模式,比如:
GDTR[DS>>3].BaseAddr + IP (IP<=SIZE) = 线性地址
DS先右移三位,然后表示GDTR的一个下标,来访问全局描述符表里面的一个表项中的基地址,再加上IP,而IP必须要小于等于段大小,防止越界访问。
- 未开启分页机制,线性地址就直接到物理地址。
- 如果开始了分页机制,线性地址(即IP中表示的逻辑地址)就等于虚拟地址。
那么如何检查是否开启了分页机制呢?(虚拟内存)
寄存器CR0的最高位PG位为0则表示未开启分页机制,为1则表示开启分页机制
而如果是虚拟地址时,知道了CR3中记录的页目录的起始地址才能完成页面映射。
如果基地址等于0,则IP就等于物理地址(未开启时)或者 虚拟地址(开启时)
而对于当代的操作系统,基地址全部设置为0,那么为什么还保留呢?是因为要向上兼容。
虚拟内存
来源:CSDN
作者:weixin_kab777
链接:https://blog.csdn.net/weixin_kab777/article/details/104052538