一、寻址
CPU有SS,DS,GS,FS,CS,SS等段寄存器,段寄存器在实模式下保存段地址,在保护模式下存储这个地址段描述结构的地址。
当一条访问内存的指令发出一个逻辑地址请求时,CPU使用如下步骤转成实际地址。
1、根据指令性质确定使用哪个段寄存器,如取数据指令就使用DS,跳转到某个地址使用CS等,这点与实模式相同
2、根据段寄存器内容找到“地址段描述结构”
3、从地址段描述结构中获得基地址
4、将指令中的地址作为位移,与段描述结构中的段长度相比来判断是否越界
5、指令的性质与描述结构的访问权限比较是否越权
6、将指令中的地址作为位移,与基地址相加获得实际的“物理地址”
首先,386中新加的GDTR(全局性段描述表寄存器)和LDTR(局部性段描述表寄存器)需要特权指令访问。
这两个寄存器存放的是“地址段描述结构”地址指针的数组
其次,把段寄存器分成高13位和低3位,高13位存放一个index,理解成数组下标,可以与GDTR或者LDTR相加得到描述结构的地址。
低3位的0-1bit存放权限级别(00最高级,11最低级),2bit表明使用GDTR(0)还是LDTR(1)
段描述结构是8字节的,根据上面的6条,主要存放了基地址、权限级别(dpi)、段长度等,具体参考第9页。
其中有一位是P标志,0说明改页不在内存中,会发生缺页异常,服务程序会从磁盘调取该页到内存,并把P置1.
如果把所有段寄存器都指向同一个描述结构,该描述结构的基地址为0,段长度设置最大,就可以覆盖0-32位的所有地址。
这样就绕过了“段地址+偏移地址”的结构,而是变成了地址一一对应,linux采用这种方式。
二、权限
i386寄存器运行级别分0-3级(0最高权限,3最低),所有指令也都有其相应的级别划分,一般用户程序运行在3层,CS寄存器指向的描述结构里的dpi位表示该程序的运行级别
三、页式管理
当不使用页式管理时,段式管理最终映射成的地址就是物理地址,当使用页式管理时,段式管理形成的地址倍称为“线性地址”。
再由线性地址通过页式管理转换成最终的物理地址。
段式管理中,连续的逻辑地址通过映射后还是连续的,但是页式管理中不一定。
线性地址结构: dir,10bit,页表目录的下标,类似图书的第几章 ,共1024章
page,10bit,页表的下标,类似图书本章开始的第几页,每章都有1024页,实际是一个结构体,还包含其他信息
offset, 12bit,页面的偏移
新增CR3寄存器指向页表目录,所以映射过程是:
1、从CR3取得页表目录地址
2、从dir中取得那个目录
3、从page中取得那个页表的基地址
4、把页的基地址加上offset就是实际的物理地址
由于页表项只需要用到高20位地址,所以页目录的低16位用来存放一些标志,例如p标志,dirty标志,是否可写
还有一个ps标志,如果是1,则线性地址的低22位全部用作位移,22位也就是4M,直接一页4M,这样就减少一个层次,速度加快。
CR4寄存器的最高位用来设置页式存储是否启用。