Intel X86系列的寻址方式总结

    这段时间工作上需要到这个,以前学过,很久不用,也就忘了(现在越来越发现自己记不住东西了,看来是心里面不再纯净了)。只好再看看书,顺便总结一下吧。
    首先说明一下,8086、8088是16位的处理器,80386以后都是32位的处理器,80286虽然是16位的处理器,但是在寻址方式上已经开始了从“实模式”到“保护模式”的过渡。btw,当我们说一个CPU是16位或32位时,指的是处理器中的ALU(算数逻辑单元)的宽度。
    8086中,数据总线的宽度是16位(通常和ALU一样),地址总线为20位,寻址空间为1M。因此,在8086中使用了分段的方法来把16位的地址映射为20位的物理地址。16位的段寄存器对应地址总线的高16位,段地址左移4位再加上访存指令中的16位地址,就形成了真正的20位的物理地址。但在这种机制下,由段寄存器确定一个“基地址”,一个进程总是可以访问由此开始的64K字节的连续地址空间,且无法加以限制。进一步,通过改变段寄存器的内容,这个进程可以随心所欲的访问内存中的任何一个单元,因此根本谈不上对系统和其它进程的保护。这就是“实模式”的最大缺点。
    过渡的80286就不讲了。
    从80386开始,进入了真正的“保护模式”。386是32位的CPU,数据、地址总线都是32位,因此寻址空间为4G。80386中对内存的管理有两种,一个是段式内存管理,一个是页式内存管理。
    先从段式内存管理说起。由于Intel是在16位CPU基础上涉及32位CPU的,因此在32位处理器中,它继承了段寄存器。由于寻址空间的增大,16位的段寄存器已不能够提供基地址了。这样就引入了一个数据结构来描述关于段的一些信息(即段描述子)。当一个访存指令发出一个内存地址时,CPU按照下面过程实现从指令中的32位逻辑地址到32位物理地址的转换:
    1.首先根据指令的性质来确定该使用哪一个段寄存器。
    2.根据段寄存器的内容,找到相应的“段描述结构”。
    3.从“段描述结构”中得到基地址。
    4.将指令中的地址作为位移,与段描述结构中规定的段长度相比,看是否越界;
    5.根据指令的性质和段描述符中的访问权限来确定是否越权;
    6.最后才将指令中的地址作为位移,与段基地址相加,得到物理地址。
    同时,在上面过程中,由于有对访问权限的检查,就实现了保护。
    上面提到的“段描述结构”实际就是段描述子。80386中有两个寄存器,分别是全局的段描述表寄存器(GDTR)和局部的段描述表寄存器(LDTR),用来指向存储在内存中的某个段描述表。原段寄存器中的高13位指明某个段描述子在段描述表中的偏移,这个偏移加上GDTR(或LDTR)中段描述表的基地址,就得到段描述子的地址。最后从段描述子中得到段的32位基地址和长度以及其它的一些信息(这些信息包括关于越界和权限检查)。
    段式内存管理只是386保护模式的一个部分,由于其效率的问题以及段是可变长度的,又发展出了页式内存管理。386处理器中有一个寄存器CR0,如果它的PG位为1,就打开了页式内存管理。
    页式内存管理是在有段式内存管理形成的地址上再加上一层地址映射。此时由段式管理形成的地址就不再是物理地址了,而是“线性地址”。段式内存管理先把“逻辑地址”映射为“线性地址”,再由页式内存管理把“线性地址”映射为“物理地址”;当不使用页式内存管理时,“线性地址”就直接用作“物理地址”。
    80386把内存分为4K的页面,每一个页面被映射到物理内存中任一块4K字节大小的空间(边界必须与4K字节对齐)。需要注意的是,在段式管理中,连续的逻辑地址经映射后在线性空间还是连续的,但连续的线性地址经映射后在物理空间却不一定连续。
    页式内存管理中,32位的线性地址划分为三个部分:10位的页目录表下标、10位的页面表下标、12位的页内地址偏移。CPU增加了一个CR3寄存器存放指向当前页目录表的指针。寻址方式就改为:
    1.从CR3取得页目录表的基地址;
    2.根据10位页目录表下标和1中得到的基地址,取得相应页面表的基地址;
    3.根据10位页面表下标和2中得到的基地址,从页面表中取得相应的页面描述项;
    4.将页面描述项中的页面基地址和线性地址中的12位页内地址偏移相加,得到物理地址。
    同时,在地址转换的过程中也有越界和权限的检查,就不赘述了。

    还有一个特例,就是所谓的“Flat(平坦)地址模式”,Linux内核就是采用这种模式的。它是在段式内存管理的基础上,如果每个段寄存器都指向同一个段描述子,而此段描述子中把段的基地址设为0,长度设为最大(4G),这样就形成了一个覆盖整个地址空间的巨大段。此时逻辑地址就和物理地址相同。形象的看,这样的地址就没有层次结构(段:偏移)了,所以叫做平坦模式,它是段式管理的特例。

    大概就这么多了,只想简单总结一下寻址方式,很多细节都没有涉及,比如描述子的具体数据结构,有兴趣的话就继续研究。顺便推荐一本书:《Intel微处理器——从8086到Pentium系列体系结构、编程与接口技术(第五版 影印版)作者:Barry B.Brey   出版社:高等教育出版社
    有空我再看看vm86模式,还不太清楚这个。

你可能感兴趣的:(Intel X86系列的寻址方式总结)