一个懒人专用文章归档神器,如果你不能成为压路机的一部分,那么你就只能成为道路的一部分 Bala~bala~

段选择符和段寄存器

汇编 懒人 1157℃ 0评论

首先看一下段选择符。段选择符为16位。为了方便查找段选择符,CPU提供了段寄存器来存放段选择符。段寄存器有cs, ss, ds, es, fs, gs(为16位),主要的有cs:代码段寄存器。包含程序指令的段;ss:栈段寄存器。指向当前程序栈的段。ds:数据段。指向静态数据或者全局数据段

段选择符的字段如下(相应的图):

其中,TI表示是存放在GDT还是存放在LDT,是0表示存放在GDT。否则存放在LDT。

    INDEX表示的是选择索引号。就是用此索引号来在GDT中检索相应的段描述符。

    RPL(requested privilege level)表示的是请求者的特权级。这里的特权指的是访问相应段的权限。在linux里面有用户态和内核态两种。这里的RPL(2位)是因为默认的是4级,linux里面使用的是0级来表示内核态,3级表示用户态。内核态能够访问用户态和内核态的地址空间和数据,用户态不可以访问内核态的数据空间(除了使用系统调用这个接口以外)。

接下来看看段描述符在内核中相应的表示(以下所有源码分析均是2.6.34):

linux/arch/x86/include/asm/desc_defs.h

  13

  14/*

  15 * FIXME: Accessing the desc_struct through its fields is more elegant,

  16 * and should be the one valid thing to do. However, a lot of open code

  17 * still touches the a and b accessors, and doing this allow us to do it

  18 * incrementally. We keep the signature as a struct, rather than an union,

  19 * so we can get rid of it transparently in the future — glommer

  20 */

  21/* 8 byte segment descriptor */

  22struct desc_struct {

  23        union {

  24                struct {

  25                        unsigned int a;

  26                        unsigned int b;

  27                };

  28                struct {

  29                        u16 limit0;

  30                        u16 base0;

  31                        unsigned base1: 8, type: 4, s: 1, dpl: 2, p: 1;

  32                        unsigned limit: 4, avl: 1, l: 1, d: 1, g: 1, base2: 8;

  33                };

  34        };

  35} __attribute__((packed));

这也就是传说中的8个字节的段描述符。每个段都会有一个段描述符。它描述了段的相应特征。具体的看相应字段。base0(占16位)和base1(占8位)和base2(占8位)组合形成了段的首字节的线性地址。

limit:存放段的最后一个内存单元的偏移量。这样就可以确定段的长度。但是这个还跟g位(占1位)有关。g:表示的是粒度。如果是0,则表示的是段的大小以字节为单位。否则,则表示的是以4k字节的倍数记。(通常一页为4k个字节)。

type字段(4位)表示的是最高位表示的是数据段还是代码段?为0则表示是数据段,为1表示是代码段。如果是数据段,则低三位表示: accessed (A)第8位, write-enable (W), and expansion-direction (E)。

如果是代码段,则低三位表示:accessed (A), read enable (R), and conforming (C)。                                                    代码段可以被execute- only或者execute/read, 设置的是read enable位。其他的先不考虑

s位表示的是系统表示。清0了则代表是系统段,存储诸如LDT这种关键的数据结构。否则为代码段或者数据段。

dpl:表示的是descriptor privilege level.表示的是描述符特权级。与上面提到的请求特权级概念内涵一样。对于为0时(表明这个描述附所代表的信息是来自内核的),表示只有当CPL为0时才可以访问这个描述符。如果为3(表明这个描述符所代表的信息来自用户态的),则表明cpl为0俄3都可以访问这个描述符。

p表示是否存在内存中。为1表示在内存中。为0表示在磁盘中。通常都是为1。因为一般不把整个段全部放到磁盘。

结合具体的内核态数据段、代码段和用户态的数据段、代码段分析如下(图):

分析如下:

如用户数据段。

Base   0x00000000表示基址为0x00000000

G      1表示粒度为4K个字节

Limit Oxfffff结合G理解如下:限制大小为0xfffff也就是(0xfffff+1)*4k=4G也就是整个用户数据段的地址空间为4G大小。

S      1表示为普通的数据段,而不是系统段

Type   10对应的位为1010,表示此描述符是数据段,此段可写。

DPL    3表示是用户态的

D/B    3这个先不考虑。

P      1表示在内存中。

转载请注明:懒人档案室 » 段选择符和段寄存器

喜欢 (0)
发表我的评论
取消评论
表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址