深入感受IA32段式存储结构

       经过几天不懈的努力,终于把保护模式下分段内存管理的机制搞得很清楚了。所以现在写些这篇文章来,是觉得可以轻松下笔了。因为在这样一次痛苦并且的快乐着的经历之前,我不敢说我可以完全掌握分段其中的来龙去脉,更别谈亲自用代码来实现了。而现在,我可以很自豪的说,我做到了,很明白的内存分段机制,在我的键盘下,一点一点的完全展现在我的面前。下面我就把这两的思路记下来,以备后用,如果偶尔被同行看见,错误之处,请给予指正,不甚感激!
       尽管我的8086汇编觉得很烂,但是,如果说段式存储,还真得从那个时候讲起。我们都知道,在8086汇编里,就已经有分段的概念,那时有CS,DS,ES,SS等段寄存器,而我们的程序也通常被放在不同的段中,如果想要进行跨段执行代码,则还要涉及,长,短跳等概念。回忆这些后面会有好处,而且可以帮你建立一个初步的段式结构。那个时候CPU工作在实模式下,8086/8088的地址总线为20位,因而,其最大的寻址空间只有1MB,而CPU的字长却是16位的,那么怎么解决16位总线访问20位地址的问题呢,于是就引入了存储器地址分段的方法。
于是就有了:物理地址=16d*段地址 + 偏移地址  这一经典的公式。呵呵
每个段的大小可达64KB,但是这显然是不够的,于是当80386出现以后,地址线已经扩展到了32位,而且机器字长也已经步入正规32位系统结构,它能够提供高达4GB的地址空间。但是,系统首先要解决如何寻址的问题。其次,随着多务处理的需求,保护模式的概念也被提出。通俗的说就是为不同级别的任务提供不同的保护级别,让各个任务,在共同相同的物理空间,但又彼此互不干扰的运行。但是多任务必然会引起内存使用的紧张,这就需要内,外存协同工作,调度的实现又要求后来的分页机制。而分页正是建立在分段的基础之上的。下面这张图可以很好的描述这样一种关系:

因此,我们的第一要务就是要实现分段机制,让我们的Sinix操作系统工作在保护模式下。好的,我们下面会按照这样的思路写:

1:如何寻址?怎样由逻辑地址转到物理地址?
2:什么是特权级?怎样在不同的特权级间跳转?不同特权级间有什么注意地方?
3:多任务是怎么实现的?

(一):好的,我们先看如何寻址。我还是会和以前的方式相比较。
在实模式下,我们会给出CS:IP这种形式的逻辑地址。这里的CS是段的基址,但是我们知道现在的段寄存器CS已经是32位,而段基址也是32位,如果全部用来存放地址,那么,所谓的保护的概念又从哪里体现呢?显然,这里的CS存放的东西已经不再和以前一样,但是一定会有基址。在保护模式下,我们把这些段寄存器存放的内容,更多时候叫做选择子。选择什么呢?肯定是段地址,不同的代码段有不同的基址,同样也有不同的选择子,然后交替的装入段寄存器,从而实现对不同段的访问。在哪选择呢?有两个地方:1:GDT(全局描述符表),2:LDT(局部描述符表)也可以说LDT是从GDT中的一个表项分出来的子表。我们先来看看他们的结构:


呵呵,上面的图不是GDT表,而是每一个表项的内容,我们就它描述符,上图我们可以知道,它的作用就是描述一个段的信息,包括基址,特权级等等。下面是访问一个线性地址的过程:




posted on 2006-03-10 01:07  Stone_石头  阅读(1537)  评论(0编辑  收藏  举报