80X86的物理地址形成(实模式+保护模式)——段式寻址


1.实模式
80X86系列CPU中,最早的是8086,它有20根地址线,可以寻址1MB(2^20)内存空间。
很自然地,如果CPU要跟主存交换信息,它也必须有20位的物理地址,但是,8086CPU内部是16位的结构,它里面跟地址有关的寄存器都是16位的(8086中跟地址有关的寄存器有五个:SI,DI,BP,SP,IP,前四个是变址寄存器,最后一个是指令指示器,它保存的是CPU将要执行的下一条指令的偏移地址),因此只能进行16位地址运算,寻找操作数的范围也只能是64KB以内,怎么办?
以下是8086的设计人员想出的办法:
a.主存分段
将1M的主存分段,每段为16位寻址的最大值(64KB)。这样,对于每一个段,我们只需要一个寄存器就可以寻址整个段。
我们把这个叫偏移地址,8086中有专门的寄存器来寄存这些地址:IP,SP,BP,SI。
b.左移获得段基址
但是不管怎样,主存还是20位的,我们能根据寄存器知道每一个段内地址的索引,怎样知道整个主存中的位置呢,也就是怎么得到基址呢?设计人员是这样想的,不就是高四位吗,好,我将寄存器的值左移四位,从逻辑上来讲,不就是20位了吗?把这个当做段的基址。(这个段首址也用专用的寄存器存放:CS,DS,SS,ES(386加了FS,GS附加数据段)四个段寄存器
这样,我们就既能寻址到主存中任意位置的物理地址了,具体如下:
对于CS(代码段):
                             物理地址PA = (CS)左移四位+(IP)
对于SS(堆栈段):
                             物理地址PA = (SS)左移四位+(SP)
对于DS(代码段):
                             物理地址PA = (DS或ES、FS、GS)左移四位+(偏移地址) ——偏移地址寄存器根据寻址方式而定

2.保护模式(保护模式下段的概念其实很模糊了)
从80386以后,CPU寄存器支持32位运算,地址线也由原来的20根扩充到32根,可以寻址4G的主存空间,仍然采用分段技术,但是物理地址的形成方式已经跟16位的完全不同了,这就是保护模式。
先解释下为什么说这个时候段的概念已经模糊了,我们回想下,为什么要出现段的概念?原因是在8086CPU地址线20根,而寄存器只有16位,所以寄存器最多给出的偏移地址是16位,所以分段,段内再进行偏移,而到386后,这个时候进入保护模式下寻址4G内存,寄存器的位数已经从原来的16位变到了32位,完全可以表示整个4G内存大段(如果这个算一个段的话)的偏移,也就是说我们直接可以用一个32位的寄存器就可以表示你想要找的物理地址了,那么Intel为什么不这么做而还是死板地要保留段寄存器并且依然是16位依然用基址+偏移地址这种很恶心的方式呢?其实有两个原因:
1.虽然寄存器已经可以全局寻址,但是对应用程序的模块化而言,分段更加便于管理;
2.Intel为了向下兼容。(其实这个完全可以用另外一种方式,比如段寄存器加到32位,但是向下兼容的时候只用16位,唉!Intel的世界我们不懂。。。也许它觉得复杂的才是牛逼的,正如现在某些所谓诗人,写些让你看不懂的好诗!我只能一遍又一遍问候他祖宗十八代。。。)
所以段寄存器依旧存在而且依然是16位,寻址方式依然是基址+偏移地址。。。
这种模式下,涉及到四个很重要的概念:段寄存器,段描述符,段描述符表,描述符寄存器(全局的和局部的),一一介绍。
段寄存器(CS,DS,SS,FS,GS,ES)
又叫段选择子,跟实模式下完全不同,虽然它们依然是16位,但是它们不再存储段基址,而是存储段描述符的索引和描述符存储方式,具体如下:
0-1位:共2位,段描述符的特权级。
2位:段描述符的存储方式。TI=0,从全局描述符表(GDT)中选择描述符,TI=1,从局部描述符表(LDT)中选择描述符。
3-15位:共13位,描述符索引。(指要找的描述符在GDT或者LDT中的偏移
段描述符:
段描述符才是真正存储段信息的地方,它由4个字组成,即八个字节,具体结构如下:
80X86的物理地址形成(实模式+保护模式) - 寒塘渡鹤影 - wuyanzan606——疏云冷月
基地址:红色区域,一共32位,是段的基地址。
段限长:浅绿色区域,一共20位。
黄色区域:
         G=0,说明段长度计量单位为字节,G=1,说明计量单位为页,即4KB
         P=0,说明该描述符不在主存中,在磁盘上,会抛出异常,P=1,则说明描述符已在主存中。
         DPL记录描述符的特权级
         TYPE比较复杂,记录段的具体属性。
其余位为保留位和系统专用位。
段描述符表:(全局描述符表,局部描述符表,中断描述符表)
—全局描述符表(GDT)
只有一个,包含8192个描述符,为64KB,包含任务共享段的描述符(如代码段,数据段,堆栈段)和所有系统段的描述符(如LDT的描述符)。
—局部描述符表(LDT)
每一个任务都有一个LDT,包含该任务的各个段的描述符。而该LDT又是一个系统段,它对应的描述符放在GDT中
—中断描述符表
2KB,最多256个中断描述符。
描述符寄存器:(GDTR和LDTR)
GDTR:共48位,高32位为全局描述符表GDT的基址,低16位存放GDT限长。
LDTR:共16位,高13位存放LDT在GDT中的索引。
好了,这几个概念就介绍这些,下面介绍如何形成线性地址(线性地址与物理地址不同,如果存在分页,则还需要再次映射,否则两者是同一概念
a.TI=0——即从全局描述符表中选择描述符。
80X86的物理地址形成(实模式+保护模式) - 寒塘渡鹤影 - wuyanzan606——疏云冷月
①从GDTR中得到GDT的基址; ②结合段选择器中的索引值和GDT找到段描述符; ③根据段描述符中的基址加上偏移地址即得到线性地址。(注意这里的偏移地址也由16位变成了32位)。
b.TI=1——即从局部描述符表中选择描述符
80X86的物理地址形成(实模式+保护模式) - 寒塘渡鹤影 - wuyanzan606——疏云冷月
 ①从GDTR中的到GDT的基址;②从LDTR中读取LDT段描述符在GDT中的索引;③根据上两步得到LDT的描述符,也就得到了LDT的基址;④从段选择器中得到该段在LDT中的描述符索引,结合上一步得到的LDT基址,从而就得到了该段描述符;⑤根据上一步的段描述符中的基址+偏移地址得到最后的线性地址。
再次重申,该线性地址并不一定是最后物理地址,如果有分页,则还需从线性地址映射到物理地址。

最后补充几个概念:
逻辑地址:段式内存管理转换之前的地址。
虚拟地址(线性地址):页式内存管理转换之前的地址。
物理地址:最终的内存地址。
  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值