【我所理解的80386编程模型】第一章:各种段

我所理解的80386编程模型

一:缘起

  这是我第二次读赵炯博士的《linux0.11内核完全注释3.0》了,在3.0版本里作者在前几章加了一些介绍性的知识。比如第三章的“内核编程语言和环境”以及第四章“80x86保护模式及其编程”,我觉得讲的是极好的。第一遍看的时候,花了好多时间,记得看懂了,但是过了一段时间又忘了,这就是没有记笔记的原因。这一次看的时候,收获也很大,所以我想做一个笔记备忘一下。

二:逻辑地址

  2.1 80386中的逻辑地址

  在8086中,一个程序的逻辑地址的形式是有段基址:段内便宜组成,比如代码段中CS:IP,数据段的DS:SI,堆栈的ES:SP。其物理地址是通过段地址左移4位加上段内偏移得到的。

  在80386中,情况复杂了一点,段选择符仍然是16位,但是段内偏移是32位,所以80386中不再是使用段选择符左移加上段内偏移的形式了。

  最重要的是得到一个段的基址,那么怎么得到一个段的基址呢?

  就是段选择符,段选择符像一个指针,它只想GDT或者LDT表中的一项。我们把表中的一项成为段描述符。

  从何说起才能最简单的介绍清楚分段的概念呢?

  (1)80x86中有一个指向GDT表基址和表长度的寄存器GDTR

  

  其中32的地址是线性地址,我因为没有看到这句话,就被一个问题困扰了好久,假如所有的逻辑地址都是通过GDT来翻译的,那么谁又来翻译GDT自己呢?后来我才明白GDT是不用翻译的,它就在线性地址空间。16位表长度的单位是Byte,而一个描述符有8个Byte,所以一个GDT表最多只能有8192个描述符。 

  (2)描述符长什么样子?

  GDT中的每一个项都是描述符,每一个描述符都是8Byte,那么80386用这8Byte做了什么呢?

  一个描述符的是由 段基址+段限长+段属性组成,其中段基址32位,段限长20位,属性12位。所以看起来是这个样子:

  

   但是实际中是这个样子:

  【我所理解的80386编程模型】第一章:各种段_第1张图片

  大概是为了寻址的方便吧。

  (3)都有哪些描述符。

  我不会详细介绍属性,但是应该知道S位决定了描述符类型,0是系统段,1是代码或数据段,然后TYPE决定了段类型,TYPE是4位,所以学过计算机的同学都知道

2^5=32,所以我们共有32种描述符,但是实际中没有那么多咪。

  下面是S=0时,16种系统段:

  【我所理解的80386编程模型】第一章:各种段_第2张图片

  也就是说,其实我们我们共有六种系统段:LDT段,TSS段,调用门,任务门,陷阱门,中断门。

  LDT段和TSS段是典型的描述符格式。就是 段基址+段限长+段属性。

  调用门是这个样子:

  【我所理解的80386编程模型】第一章:各种段_第3张图片

  任务门是这个样子的:

  【我所理解的80386编程模型】第一章:各种段_第4张图片

  注意这个段选择符应该指向一个TSS,而当程序通过任务门切换的时候,系统会检测任务门描述符的特权检查,但是不对TSS检测。

  陷阱门和中断门的布局是这个样子。

  

  请注意对比和典型的描述符的不同。

  下面是S=1时,16种代码段或数据段:

  【我所理解的80386编程模型】第一章:各种段_第5张图片

  其中下扩,可读写数据段可以用作栈。

【我所理解的80386编程模型】第二章:内存分页

你可能感兴趣的:(编程)