数据段描述符和代码段描述符(一)——《x86汇编语言:从实模式到保护模式》读书笔记10

一、段描述符的分类

在上一篇博文中已经说过,为了使用段,我们必须要创建段描述符。80X86中有各种各样的段描述符,下图展示了它们的分类。

段描述符的分类

看了上图,你也许会说:天啊,怎么这么多段描述符啊!我可怎么记住呢?哭泣的脸 别担心,我会在以后的博文中,跟随原书的作者,为您逐步介绍。我们的学习是循序渐进的,所以不要求一下子掌握所有东西。我们的原则是:用到什么学什么。我们今天的重点是“存储段描述符”。

二、段描述符的通用格式[1]

段描述符是GDT和LDT中的一个数据结构项,用于向处理器提供有关一个段的位置、大小以及访问控制的状态信息。每个段描述符的长度是8个字节,含有3个主要字段:

  • 段基地址
  • 段限长
  • 段属性

段描述符通常由编译器,链接器,加载器或者操作系统来创建,但绝不是应用程序。

下图给出了所有类型的段描述符的一般形式。

捕获

 

1.段限长字段Limit

用于指定段的长度。处理器会把段描述符中两个段限长字段组合成一个20位的值,并根据颗粒度标志G来指定段限长Limit值的实际含义。

如果G=0,则Limit值的单位是B,也就是说Limit的范围可以是1B到1MB;

如果G=1,则Limit值的单位是4KB,也就是说Limit的范围可以是4KB到4GB。

根据段类型字段TYPE中的段扩展方向标志E,处理器可以以两种不同的方式使用Limit。

E=0:表示向上扩展的段(简称上扩段),逻辑地址中的偏移值范围可以从0到Limit;

E=1:表示向下扩展的段(简称下扩段),逻辑地址中的偏移范围可以从Limit到0xFFFF(当B=0时)或者0xFFFF_FFFF(当B=1时)。关于B位,后面将解释。

2.基地址字段Base

该字段定义在4GB线性地址空间中一个段的字节0所处的位置。也许你觉得这句话不好理解,我们换一种说法:对于一个逻辑地址,如果段内偏移为0,那么这个逻辑地址对应的线性地址就是Base;如果段内偏移为X,那么这个逻辑地址对应的线性地址就是Base+X;

段基地址可以是0~4GB范围内的任意地址(这同实模式不同,实模式下段基地址要求16字节对齐),但是,为了让程序具有最佳性能,还是建议段基地址对齐16字节边界。

3.段类型字段TYPE

该字段用于指定段或者门(Gate)的类型、说明段的访问种类以及段的扩展方向。该字段的解释依赖于描述符类型标志S;TYPE字段的编码对代码段、数据段或者系统描述符都不同。

4.描述符类型标志S

S=0:表示存储段描述符。所谓“存储段”,就是存放可由程序直接进行访问的代码和数据的段。说白了,存储段就是代码段或者数据段。

S=1:表示系统描述符。

5.描述符特权级字段DPL

用于指明描述符的特权级。特权级范围从0(最高)到3(最低)。DPL字段用于控制对段的访问。

6.段存在标志P

用于指出一个段是在内存中(P=1)还是不在内存中(P=0).

7.D/B(默认操作数大小/默认栈指针大小和上界限)

对于代码段,此位称为“D”位;对于栈段,此位称为“B”位。我们在后文会说。

8.颗粒度标志G

该字段用于确定段限长字段Limit值的单位。

如果G=0,则Limit值的单位是B;

如果G=1,则Limit值的单位是4KB;

注意:这个字段不影响段基地址的颗粒度,基地址的颗粒度总是以字节为单位。

9.可用和保留位

L位(就是上图灰色的那个位):是64位代码段标志,保留此位给64位处理器使用。目前,我们将此位置“0”即可。

AVL:是软件可以使用的位,通常由操作系统来用,处理器并不使用它。

 

三、数据段描述符[1]

当S=1且TYPE字段的最高位(第2个双字的位11)为0时,表明是一个数据段描述符。

下图是数据段描述符的格式。

数据段描述符

1.B位(默认栈指针大小和上界限)

对于栈段(由SS寄存器指向的数据段)来说,该位用来指明隐含堆栈操作(如PUSH、POP或CALL)时的栈指针大小。

B=0:使用SP寄存器

B=1:使用ESP寄存器

同时,B的值也决定了栈的上部边界。

B=0:栈段的上部边界(也就是SP寄存器的最大值)为0xFFFF;

B=1:栈段的上部边界(也就是ESP寄存器的最大值)为0xFFFF_FFFF.

2.A位(已访问)

用于表示一个段最近是否被访问过(准确地说是指明从上次操作系统清零该位后一个段是否被访问过)。

当创建描述符的时候,应该把这位清零。之后,每当该段被访问时(准确地说是处理器把这个段的段选择符加载进段寄存器时,也许你不懂这句话,没有关系,现在忽略就可以了。)它就会将该位置“1”;对该位的清零是由操作系统负责的,通过定期监视该位的状态,就可以统计出该段的使用频率。当内存空间紧张时,可以把不经常使用的段退避到硬盘上,从而实现虚拟内存管理。

3.W位(可写)

指示段的读写属性。

W=0:段不允许写入,否则会引发处理器异常中断;

W=1:允许写入。

4.E位(扩展方向)

E=0:表示向上扩展的段(简称上扩段),逻辑地址中的偏移值范围可以从0到Limit;

E=1:表示向下扩展的段(简称下扩段,通常是栈段),逻辑地址中的偏移范围可以从Limit到0xFFFF(当B=0时)或者0xFFFF_FFFF(当B=1时)。

四、代码段描述符[1]

当S=1且TYPE字段的最高位(第2个双字的位11)为1时,表明是一个代码段描述符。

下图是代码段描述符的格式。

代码段描述符

1.D位(默认操作数大小)

用于指出该段中的指令引用有效地址和操作数的默认长度。

D=0:默认值是16位的地址和16位或者8位的操作数;

D=1:默认值是32位的地址和32位或者8位的操作数;

说明:指令前缀0x66可以用来选择非默认值的操作数大小,指令前缀0x67可以用来选择非默认值的地址大小。

2.A位(已访问)

与数据段描述符中的A位相同。

3.R位(可读)

R=0:代码段不可读,只能执行。

R=1:代码段可读,可执行。

也许有人会问,当R=0时,既然代码段不可读,那处理器怎么从里面取指令执行呢?事实上,这里的R属性并非针对处理器,而是用来限制程序的行为。当常数或者静态数据被放在了一个ROM中时,就可以使用一个可读可执行的代码段,然后通过使用带CS前缀的指令,就可以读取代码段中的数据。

注意:

  • 在保护模式下,代码段是不可写的。
  • 堆栈段必须是可读可写的数据段。

4.C位(一致性)

C=0:表示非一致性代码段。这样的代码段可以被同级代码段调用,或者通过门调用;

C=1:表示一致性代码段。可以从低特权级的程序转移到该段执行(但是低特权级的程序仍然保持自身的特权级)。

注意:所有的数据段都是非一致性的,即意味着它们不能被低特权级的程序或过程访问。然而与代码段不同,数据段可以被更高特权级的程序或过程访问,而无需使用特殊的访问门。

有关特权级和特权级检查我们以后再讨论,这里对上面的概念了解即可,不用深究。

最后,补充一张图表,也是引用自赵炯的《Linux内核完全剖析》。

 

表4-3

参考资料:

[1]:赵炯,《Linux内核完全剖析》,机械工业出版社. 4.3.4节

### 回答1: 这视频介绍了x86汇编语言下,如何从实模式切换到保护模式。 首先,视频介绍了实模式的特点和局限性。实模式下,CPU只能寻址1MB的内存空间,同时所有的程序都需要运行在同一个特权级下,对于大型程序和操作系统而言非常不利。 接着,视频介绍了如何切换到保护模式保护模式下,CPU可以通过基地址和选择器来访问4GB的内存空间,同时程序可以运行在不同的特权级下。切换到保护模式的关键步骤包括:设置GDT和IDT表、开启A20线、设置CR0寄存器、跳转到保护模式代码等。 最后,视频演示了如何编写汇编代码来实现保护模式的切换。代码包括定义GDT和IDT表、开启A20线的函数、设置CR0寄存器的函数,以及跳转到保护模式代码的函数。通过这视频的学习,我们了解了从实模式保护模式的切换原理和实现方法,对于深入理解操作系统和底层编程有着重要的意义。 ### 回答2: x86汇编语言是计算机的底层语言,包括实模式保护模式两种运行模式。实模式是早期计算机的一种运行模式,它的内存访问方式简单,容易理解。在实模式下,整个物理内存空间可以直接寻址,但同时也带来一些安全问题。为了保护内存和提高计算机运行的稳定性,最终出现了保护模式保护模式x86汇编语言的一种运行模式,它可以让计算机利用内存管理单元(MMU)来对内存进行隔离和保护。在保护模式下,内存空间被分为多个,并为每个赋予相应的权限和特权级别。这样可以有效保护计算机的内存空间,避免程序之间相互侵入和破坏。 保护模式的运行需要经过一系列的初始化,包括:打开地址线扩展、禁用中断、打开分页等操作。这些操作可以通过设置控制寄存器和描述符表来实现。 在保护模式下,程序运行的特权级别由RPL(Requested Privilege Level)和CPL(Current Privilege Level)两个标志位来控制。CPL位于代码数据的选择子中,代表当前运行程序的权限级别,而RPL位于代码选择子和数据选择子中,用来判断程序是否有权访问对应的。 在保护模式下,虚拟地址需要经过地址转换才能转换成物理地址,这需要使用页表来对虚拟地址进行映射。页表和页目录存储在内存中,需要通过控制寄存器来取出相应的值进行地址转换。 总之,x86汇编语言的实模式保护模式都有各自的特点和应用场合,学习x86汇编语言需要深入理解这两种运行模式的原理和实现过程。 ### 回答3: x86汇编语言是计算机硬件操作指令的编程语言,是本质上依赖于CPU架构和指令集的语言。根据其中对内存的处理方式的不同,x86汇编语言可以分为实模式保护模式。 实模式是指CPU直接访问物理内存,地址总线是20位,内存寻址空间最大为1MB。实模式下的程序可以访问系统资源,例如中断处理、内存读写等操作。但实模式下内存空间过小,程序出错容易导致系统崩溃。 保护模式是一种更加灵活和安全的工作状态,地址总线扩展到了32位,理论内存访问空间可以达到4GB以上。保护模式下内存被划分为多个,程序可以在相互独立的之间进行操作,可以在级别上分配权限,从而提高代码的安全性。同时,保护模式也支持虚存技术,通过硬件的支持,可以将程序的实际运行数据放入物理内存和虚拟内存的组合体内,从而可以利用硬盘来进行虚拟内存的支持,使得多个程序在同一系统上运行时不会相互干扰,同时提高系统的稳定性。 因此,在现代操作系统上,保护模式是必需的。x86汇编语言需要不同的功能选项来在实模式保护模式之间进行转换。在视频中,我们可以学习如何从实模式切换到保护模式,并掌握如何在保护模式下使用不同的功能选项。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值