OS 和 CPU 紧密相关,可以说, CPU 是硬件化的 OS , OS 是软件化的 CPU 。 OS 和 CPU 第一接触点就是寄存器,要能够做到看到寄存器就知道其可能在 OS 中的用途,相应的 OS 可能与比配对的数据结构,反之,看到 OS 时,就要想到其需要什么样的物理寄存器,要什么样的 CPU ,只有这样才能做到 OS 与 CPU 的完美合一,只懂一个,那是二流水平。
另外,指令将 OS 数据结构和 CPU (寄存器)联合起来的唯一桥梁 。
X86 有个叫做任务寄存器的 TR 段寄存器,当从用户空间到系统空间时, CPU 就自动根据 TR 的指针从 TSS 寄存器中得到当前进程的 SS 和 ESP 两个寄存器的值。可以说, TR 和 TSS 寄存器就是为了进行系统空间和用户空间切换而生的,与之配对的是 ltr 和 str 指令。
这两条指令是特权指令,只有在系统空间时才能执行,这两个指令可真是意味深长,它简单3个字母 CPU 却要做很多的事情:根据 TR 的指令从 TSS 中得到当头中线程的系统空间堆栈,把寄存器内容压入堆栈 ,根据 IDTR 的指引从中断向量表中得到 CS 和 EIP 的值。如此多的事情,显然要很多个时钟周期才能完成,这也证明了 str 和 ltr 是长周期指令,这才有了后来的快速系统调用指令 sysenter 和 sysexit 。那么这两个指令后面又有哪些寄存器参与呢?其速度又是如何呢?可以好好分析一下。
Windows 内核有个特殊要求:只要 CPU 在内核中运行,就要使得段寄存器 FS 指向一个叫做 KPCR 的数据结构。
在 32 位保护模式中,段寄存器其中并不是一个段的基地址,而是一个描述符号,是一个 16 位的选择码,指向全局描述表 GDT 中某个 64 位的表项。相当于说, X86 通过加入描述符这一中间级,加大了寻址能力。否则,1个段寄存器只能对应一个段,现在可以选择 2^16 个段。加入中间描述符扩展寻址能力,是 X86 的通用做法 。
描述符的结构是寄存器级的,也就是不同的位表示不同的意思,这样能增加信息的容量。
因为 Windows 允许在内核中进行系统调用,所有才有先前模式一说,而 Linux 根本不允许在内核里面进行系统调用,所以根本没这一说。