您的位置:首页 > 其它

1.2 Intel X86 CPU系列的寻址方式

2013-06-09 15:59 381 查看
  所谓X86系列,是指Intel从16位微处理器8086开始的整个CPU芯片系列,系列中的每种型号都保持与以前的各种型号兼容,主要有8086、8088、80186、80286、80386、80486以及以后各种型号的Pentium芯片。

  在X86系列中,8086和8088是16位处理器,而从80386开始为32位处理器,80286则是该系列从8088到80386,也就是从16位到32位过渡的一个中间步骤。当我们说一个CPU是16位或32位时,指的是处理器中ALU算术逻辑单元的宽度。

  8086中采用16位CPU和1M字节的内存地址空间即20位的地址总线宽度。Intel使用分段的方法来处理ALU宽度与地址总线宽度的空隙:

  Intel在8086CPU中设置了四个段寄存器:CS、DS、SS和ES。每个段寄存器都是16位的,对应于地址总线中的高16位。每条访内指令中的内部地址都是16位的,但是在送上地址总线之前都在CPU内部自动的与某个段寄存器中的内容相加,形成一个20位的实际地址。这样就实现了从16位内部地址到20位实际地址的转换,或者映射。段寄存器的内容对应于20位地址总线中的高16位,所以在相加时实际上是拿内部地址的高12位与段寄存器中的16位相加,而内部地址中的低4位保留不变。这个方法与“段式内存管理”相似,但缺少地址空间的保护机制。对于每一个由段寄存器的内容确定的基地址,一个进程总是能够访问从此开始的64k的连续空间,而无法加以限制。同时,用来改变段寄存器内容的指令也不是特权指令,这样就可以通过改变段寄存器的内容,一个进程可以随心所欲的访问内存中的任何一个单元,而不受限制。这种模式缺乏对内存空间的保护,为区别于后来的“保护模式”,就成为“实地址模式”。

  8036是32位CPU。为了与之前兼容,Intel选择了在段寄存器的基础上构筑保护模式的构思,并且保留段寄存器为16位(这样才可以利用原有的四个寄存器),但是又添加了两个段寄存器FS和GS。为了实现保护模式,仅仅用段寄存器来确定一个基地址是不够的,至少还得要有一个地址段的长度,并且还需要一些其他的信息,如访问权限之类。所以需要一个数据结构而并非一个单纯的基地址。Intel设计的基本思路是:在保护模式下改变段寄存器的功能,使其从一个单纯的基地址变成指向这样一个数据结构的指针。这样,当一条访问内存指令一个内存地址时,CPU就可以这样归纳出实际上应该放上数据总线的地址:

1、根据指令的性质来确定应该使用哪一个段寄存器

2、根据段寄存器的内容,找到相应的地址段描述符结构

3、从结构中得到基地址

4、将指令中发出的地址作为位移,与段描述符结构中规定的段长度相比,看是否越界

5、根据指令的性质和段描述符中的访问权限来确定是否越权

6、将指令中发出的地址作为偏移,与基地址相加而得出实际的物理地址。

  80386 CPU中增设了两个寄存器:全局性的段描述表寄存器GDTR和局部性的段描述符表寄存器LDTR,分别可以用来指向存储在内存中的一个段描述结构数组,或者称为段描述表。由于这两个寄存器时新增设的,不存在于原有的指令是否兼容的问题,访问这两个寄存器的专用指令便设计成“特权指令”。

  段寄存器的高13位用作访问段描述表中具体描述符结构的下标。GDTR或LDTR中的段描述符表指针和段寄存器中给出的下标结合在一起,才决定了 具体的段描述符表项在内存中的什么地方,也可以理解成,将段寄存器中的低3位屏蔽后与GDTR或LDTR中的基地址相加得到描述符表项的起始地址。因此无法通过修改描述符表项的内容来玩弄诡计,从而起到保护的作用。

  在80386的段式内存管理的基础上,如果把每个段寄存器都指向同一个描述项,而在该描述项中将基地址设为0,并将段长度设为最大,这样便形成一个从0开始覆盖真个32位地址空间的一个整段。由于基地址为0,此时的物理地址与逻辑地址相同,CPU放到地址总线上的地址就是在指令中给出的地址。这样的地址有别于“段寄存器/位移量”构成的“层次式”地址,所以Intel称其为“Flat“地址。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: