内核学习之段寄存器

来源:互联网 发布:阿里云数据库odbc 编辑:程序博客网 时间:2024/04/28 16:32

内核学习之段寄存器

关于段寄存器的介绍大部分只是介绍其分类和在寻址中的应用,很少提到段寄存器如何去寻址的。这几天一直在纠结着方面的内容,今天算是大体明白了吧!

还是首先提一下段寄存器的作用和分类。在8086模式下,对内存的访问由段基址和段内偏移共同组成的。段寄存器存放的即各个分段的段基址。并指示了4个正在使用的逻辑段,包括代码段寄存器CS、堆栈段寄存器SS、数据段寄存器DS和附加段数据寄存器ES。代码段寄存器CS存放正在执行的代码的段基址,堆栈寄存器SS存放的是当前堆栈的段基址,数据段寄存器DS存放的是当前数据段的段基址,ES为附加数据段的段基址。

深入了解段寄存器,我们首先介绍另一个概念GDT(全局描述符表),在计算机刚刚启动的时候首先运行在real mode(实模式)下,在实模式下计算机用20位寻址(包括bios和内存寻址)。20位可以寻址1M的空间,这20位的地址由16位的段基址和16位的段内偏移构成。物理地址=左移4位的段地址+偏移地址。也即是段内偏移寻址空间为00000H~ffff0H.

为了提高cpu的寻址空间,在保护模式下32位的CPU可以寻址32空间,即最大为4G空间。在保护模式下内存管理方式有两种,段模式和页模式,在此只考虑分段模式。在32位的系统中,段基址和段内偏移都用32位,因此,每个段的大小最大可为4G。也可易知想要描述一个段必须使用64位去描述。但是intel为了向后兼容段寄存器的大小仍是16bit,所以在此使用一个数组存放64位的段描述符,而将寄存器中的值作为下标索引间接引用。这个描述符表就是GDT

保护模式下的段寄存器结构如下

 

段选择器的16位具体作用是,index用于索引GDT表,T1用于区分GDTLDT表,RPL用于区分优先级。

GDT的索引中,每个GDT在内存中都有一个特定的地址,在创建GDT之后,会将GDT的地址赋给一个叫GDTR的寄存器,该寄存器中存放的值就是GDT的入口。以后再调用GDT的时候就可以直接引用该寄存器。上文中段寄存器的index就是在GDT的索引的段基址的偏移量。由此可见GDT中段基址的个数最多为2的13次方个。另外,GDTR+index就是索引的段在GDT中的位置。在获取了段基址之后加上逻辑地址的offset,就可以得到物理地址,每个系统只有一个唯一的GDT表。与之对应的为LDTLDT为局部变量表。每个引用程序都有一个LDTGDT可以看成LDT的一级索引。

在GDT和LDT中存放的是段描述符,段描述符为64位,这其中记录了段基地址和段限长等方面的内容。


除了内存的段管理机制,还有分页管理机制。具体内容还有待进一步学习。

 

0 0
原创粉丝点击