GDT 表与段选择子等解析

article/2025/9/19 3:15:37

来源:https://blog.csdn.net/qq_37653144/article/details/82821540

https://blog.csdn.net/yeruby/article/details/39718119

https://blog.csdn.net/lindorx/article/details/89410113

全局描述表(GDT Global Descriptor Table):在保护模式下一个重要的数据结构。

GDT可以被放在内存的任何位置,那么当程序员通过段寄存器来引用一个段描述符时,CPU必须知道GDT的入口,也就是基地址放在哪里,所以Intel的设计者门提供了一个寄存器GDTR用来存放GDT的入口地址,程序员将GDT设定在内存中某个位置之后,可以通过LGDT指令将GDT的入口地址装入此寄存器,从此以后,CPU就根据此寄存器中的内容作为GDT的入口来访问GDT了。
GDT是保护模式所必须的数据结构,也是唯一的–不应该,也不可能有多个。另外,正象它的名字(Global Descriptor Table)所揭示的,它是全局可见的,对任何一个任务而言都是这样。
除了GDT之外,IA-32还允许程序员构建与GDT类似的数据结构,它们被称作LDT(Local Descriptor Table),但与GDT不同的是,LDT在系统中可以存在多个,并且从LDT的名字可以得知,LDT不是全局可见的,它们只对引用它们的任务可见,每个任务最多可以拥有一个LDT。另外,每一个LDT自身作为一个段存在,它们的段描述符被放在GDT中。

gdt表在x86架构中用来存储内存的分段信息,通过段选择子进行访问,表的大小=0x10000=65536字节,每个表项占8字节,第一个表项为空,不使用,因此一共有8191个可用表项。表项结构如下

在这里插入图片描述
(图片来自https://blog.csdn.net/yeruby/article/details/39718119)
在这里插入图片描述

段界限表示段边界的扩展极值,即最大扩展到多少或最小扩展到多少。扩展方向只有上下两种,对于数据段和代码段,段的扩展方向是向上,即从低地址向高地址扩展,此时的段界限用来表示段内偏移的最大值(上界);对于栈段,段的扩展方向是向下,即从高地址向低地址扩展,此时的段界限表示段内偏移的最小值(下界)。无论是向上还是向下,段界限都表示段的边界。段界限字段给出的只是数值,其单位(或称粒度)则在G位中给出,G位为0则粒度为B,为1则为4KB。因此段界限边界值的计算公式为:

(段界限字段值+1)*(粒度大小)- 1

内存访问需要用到“段基址:段内偏移地址”,段界限其实是用来限制段内偏移地址的,段内偏移地址必须位于段描述符给出的范围之内,否则CPU会抛出异常。任何超范围的偏移地址都被认为是非法的,CPU会捕获这个异常。

段基地址为该段的首地址,占用32bit;type说明了段的属性,网络资料很多,不再详述,占用4bit;

DPL为段的权限,占用2bit,只有访问程序的权限高于等于该段的权限才能使用这个段,权限分为4级,从高到低为0、1、2、3;

P=1说明该段可以使用,否则将当作该段不存在,如果使用段选择子强行访问会发生段异常,中断号为11;

AVL由软件设定,cpu不管这个位;

D/B有两种:当这个段被type设置为代码段时,D=1代表这是32位的程序,D=0代表这是16位的程序;如果是向下拓展的数据段,则称为B位,B=1代表最大可访问范围是4GB,B=0代表最大可访问范围是64k,如果表示的是堆栈段,则B=1,使用esp寄存器作为栈顶寄存器,否则使用sp寄存器

属性字段中的type字段用来指定段描述符的类型,而S位的数值决定了type字段中不同位的含义。一个段描述符首先分为两大类,要么是系统段(S位置0),要么是非系统段(S位置1),或称数据段。对于CPU而言,凡是硬件运行需要用到的东西都可称之为系统(如硬件在内存中的映射),凡是软件需要用到的东西(操作系统也是软件,对CPU而言在这一层面它与用户程序无区别)都是数据。无视是代码还是数据,都是作为硬件的输入,因此我们常说的代码段在段描述符中也属于数据段(非系统段)。type字段要和S字段配合才能确定段描述符的确切类型,只有S字段的值确定后type字段的值才有意义。

段描述符的type类型
系统段系统段类型第3~0位说明
3210
未定义0000保留
可用的80826 TSS0001仅限286的状态段
LDT0010局部描述符表
忙碌的80826 TSS0011仅限286,type中的第1位称为B位,若为1,则表示当前任务忙碌,由CPU将此位置1
80826调用门0100仅限286
任务门0101任务门标识(现代操作系统中很少用到)
80826中断门0110仅限286
80826陷阱门0111仅限286
未定义1000保留
可用的80836 TSS1001386及以上的CPU的TSS
未定义1010保留
忙碌的80836 TSS1011386及以上的CPU的TSS
80836调用门1100386及以上的CPU的调用门
未定义1101保留
中断门1110386及以上的CPU的中断门
陷阱门1111386及以上的CPU的陷阱门
对于非系统段,按代码段和数据段划分,这4位分别由不同的意义
非系统段内存段类型

X

RCA说明
代码段100*只执行代码段
110*可执行、可读代码段
101*可执行、一致性代码段
1111可执行、可读、一致性代码段
数据段

X

W

R

A说明
000*只读数据段
010*可读写数据段
001*只读,向下扩展的数据段
011*可读写,向下扩展的数据段

表中的A表示Accessed,由CPU来设置,每当该段被CPU访问过后,CPU将该段的段描述符中的A位置1。

C表示一致性(Conforming)代码段,也称为依从代码段。与访问权限有关,C为1时表示该段是一致性代码段,为0时则表示改段是非一致性代码段。

R即Read,为1表示可读,为0则表示不可读。这个属性一般用来限制指令对代码段的访问,对于CPU而言,这个标志位不起作用,也就是说即使R为0,CPU一样可以访问该段。

X即Executable,用来标识该段是否可执行。

E即Extend,用来表示段的扩展方向,0表示向上扩展(从低地址到高地址),1表示向下扩展(从高地址到低地址)。

W即Writable,用来表示段是否可写。

非系统段,另一种更清晰的描述:
在这里插入图片描述
在这里插入图片描述

段选择子是什么?
引用GDT和LDT中的段描述符所描述的段,是通过一个16-bit的数据结构来实现的,这个数据结构叫做Segment Selector——段选择子。它的高13位作为被引用的段描述符在GDT/LDT中的下标索引,bit 2用来指定被引用段描述符被放在GDT中还是到LDT中,bit 0和bit 1是RPL——请求特权等级,被用来做保护目的。如图所示:

在这里插入图片描述

前面所讨论的装入段寄存器中作为GDT/LDT索引的就是Segment Selector,当需要引用一个内存地址时,使用的仍然是Segment:Offset模式,具体操作是:在相应的段寄存器装入Segment Selector,按照这个Segment Selector可以到GDT或LDT中找到相应的Segment Descriptor,这个Segment Descriptor中记录了此段的Base Address,然后加上Offset,就得到了最后的内存地址。

段选择子包括三部分:描述符索引(index)、TI、请求特权级(RPL)。它的index(描述符索引)部分表示所需要的段的描述符在描述符表的位置,由这个位置再根据在GDTR中存储的描述符表基址就可以找到相应的描述符。然后用描述符表中的段基址加上逻辑地址(SEL:OFFSET)的OFFSET就可以转换成线性地址,段选择子中的TI值只有一位0或1,0代表选择子是在GDT选择,1代表选择子是在LDT选择。请求特权级(RPL)则代表选择子的特权级,共有4个特权级(0级、1级、2级、3级)。
关于特权级的说明:任务中的每一个段都有一个特定的级别。每当一个程序试图访问某一个段时,就将该程序所拥有的特权级与要访问的特权级进行比较,以决定能否访问该段。系统约定,CPU只能访问同一特权级或级别较低特权级的段。
例如给出逻辑地址:21h:12345678h 转换为线性地址的步骤如下:
(1)、选择子SEL=21h=0000000000100 0 01b 它代表的意思是:选择子的index=4即选择GDT中的第4个描述符;TI=0代表选择子是在GDT选择;最后的01代表特权级RPL=1
(2)、OFFSET=12345678h若此时GDT第四个描述符中描述的段基址(Base)为11111111h,则线性地址=11111111h+12345678h=23456789h

段寄存器实际是 96 位
选择子 16 位
属性 16 位
基地址 32 位
界限 32 位。
其中属性实际有效的是 12位,如上所属。而这 16 位刚好来自 上面 GDT 表中的那 16 位(其中限长 9…16 在这里忽略)
界限 32 位。如上面所说是 20位。实际根据G位确定(G位为0则粒度为B,为1则为4KB。)
20位最大值就是 0XFFFFFF 。
如果G 为0 则是 0X00FFFFFFFF
如果G 为1 则是 0XFFFFFFFFFF


http://chatgpt.dhexx.cn/article/wJ9U9GWu.shtml

相关文章

GDT和GDTR

文章目录 GDTR和GDTGDT和GDTR关系GDTR的结构GDT的结构如何在MBR中建立GDT和GDTR? GDTR和GDT GDT和GDTR关系 GDT是global descriptor table,全局描述符表,它是描述符组成的一张描述符表。描述符就是段描述符它用来描述一个段的信息,由8个字节…

GDT,LDT,GDTR,LDTR

GDT,LDT,GDTR,LDTR 前言全局描述符表GDT局部描述符表LDT中断描述符表IDT段选择子任务寄存器TR实例1:访问GDT2:访问LDT 前言 所谓工作模式,是指CPU的寻址方式、寄存器大小、指令用法和内存布局等。 实模式 段基址:段内偏移地址”产生的逻辑地…

GDT和LDT详解

1.GDT 我们回顾一下实际的操作系统的内存关系: ​ 程序/进程 → 映射 段 表 逻辑地址 → segment unit 段 基 址 偏 移 地 址 虚拟地址 → page unit 页 表 物理内存地址 \text{程序/进程}\overset{段表}{\xrightarrow[\text{映射}]{}} \text{逻辑地址}\overset{段基址偏移…

GDT(全局描述符表)和LDT(局部描述符表)

Home > GDT(全局描述符表)和LDT(局部描述符表) 每个程序都有自己的LDT,但是同一台计算机上的所有程序共享一个GDT。LDT描述局部于每个程序的段,包括其代码、数据、堆栈等。GDT描述系统段&#xff0c…

什么是数据可视化?

到底什么是数据可视化?带你一窥究竟~ 技术人最不该忽视可视化数据分析! 导读:在这个“人人都是数据分析师”的时代,大企业的同学几乎都在参与数据的采集、加工与消费。数据可视化作为连接“加工——消费”的重要一环…

当下最火的中台到底是个什么鬼,看完这一篇最通俗易懂的文章后,你就会彻底明白了!...

公众号关注 「奇妙的 Linux 世界」 设为「星标」,每天带你提升技术视野! 背景 自从阿里巴巴现任CEO逍遥子在2015年提出”大中台,小前台”战略以来,关于”什么是中台”,可谓是一石激起千层浪,大量文章在描述…

STD::是什么?

【&#xff23;&#xff0b;&#xff0b;】std&#xff1a;&#xff1a;是什么&#xff1f; 引例&#xff1a; #include<iostream> int main() {std::cout<<"我喜欢C";//输出一句话std::cout<<std::endl;//换行return 0; } 1.std是什么&#xff1…

C语言中 1%3,算术什么意思啊 算数什么意思

算术什么意思啊 算数什么意思以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 算术是什么意思 数学 什么是算术和 算术和是正数的和,即绝对值的和,例如2+13.5+7,Ge个数值皆为正且相加。  主要区别于代数和,…

matlab语句temp,maxtemp什么意思 will什么意思

maxtemp什么意思 will什么意思以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! Min Temp 和 Max Temp 是什么意思 最小的Temp和最大Temp Temp: Chang用的办公软件和其他应用程序通常会临时保Cun用户的工作结果,…

html 玫瑰花

简易html 代码玫瑰花 <!DOCTYPE html> <html><head><meta charset"UTF-8"><title>玫瑰</title><style type"text/css"> #shusheng { position: absolute; width: 100%; height: 100%; text-align: center; } &…

计算并输出所有的玫瑰花数

如果一个n位正整数等于它的n个数字的n次方和&#xff0c;则称该数为n位自方幂数。四位自方幂数称为玫瑰花数。编程计算并输出所有的玫瑰花数。 #include <stdio.h> #include <math.h>int main() {for (int i 1000; i < 10000; i){if (i pow(i%10, 4) pow((i/…

C语言代码:玫瑰花

前文 在古希腊神话中&#xff0c;玫瑰花集爱与美于一身&#xff0c;既是美神的化身&#xff0c;又溶进了爱神的血液&#xff0c;所以它所代表的含义是爱情。 我们应该用玫瑰花来表达我们的爱意&#xff0c;但是好多的恋人都是因为异地而没有办法去买一束新鲜的玫瑰去送给自己的…

七夕玫瑰花合集

图片来源&#xff1a;百度动图 一年一度的七夕又快到了&#xff0c;用Python画一朵玫瑰花送给你的那个TA吧图片。更多表白代码可以到”阿黎逸阳的代码“公众号中翻看表白合集中的文章。 一、绘制结果 1. 玫瑰花1 2. 玫瑰花2 二、画玫瑰花代码 1. 用turtle库画一朵玫瑰花版本1 #…

C++玫瑰花源码

#include "stdafx.h" #include <graphics.h> #include <conio.h> #include <math.h> // 定义全局变量 int rosesize 500; int h -250; // 定义结构体 struct DOT { double x; double y; double z; double red; // 红…

Python玫瑰花

用Python画一朵玫瑰花&#xff08;附带源码&#xff09; 需要的模块包 turtle(内置包) 源码部分 import turtle# 设置初始位置 turtle.penup() turtle.left(90) turtle.fd(200) turtle.pendown() turtle.right(90)# 花蕊 turtle.fillcolor("red") turtle.begin_fill…

C语言玫瑰花

效果图&#xff0c;如果想要更改颜色&#xff0c;可以在代码最后一行system处修改。 #include <stdio.h> #include <math.h>const int max_iterations 128; const float stop_threshold 0.01f; const float grad_step 0.01f; const float clip_far 10.0f;cons…

如何买玫瑰?

代码和任务 /*copyright(c)2015 csdn学院 *All right reserved. *文件名称&#xff1a;main.c *作者&#xff1b;张如田 *完成日期&#xff1a; *版本号&#xff1a; *任务描述&#xff1a;小慧过生日&#xff0c;小明&#xff08;小明真忙&#xff09;要买鲜花送她。每枝红玫瑰…

买玫瑰

要求&#xff1a;小慧过生日&#xff0c;小明&#xff08;小明真忙&#xff09;要买鲜花送她。每枝红玫瑰5元&#xff0c;满5支送1枝&#xff0c;满20枝送5枝。小明一共有n(n>10)元钱&#xff0c;最多能买到多少&#xff1f; 样例输入&#xff1a;135 样例输出&#xff1a;3…

中软国际实训全记录——第三天

中软国际实训第三天——认识ssm与搭建ssm 1、ssm框架基本概念1.1、Spring1.2、SpringMVC1.3、MyBatis 2、建立ssm项目2.1、新建Maven项目2.2、添加项目主要目录2.3、项目内容编码2.4、使用Tomcat运行项目2.5、建立数据库的连接2.6、对数据库中数据进行查询2.7、使用控制器显示查…

中软国际实训全记录——第六天

中软国际实训第六天——SpringSecurity的架构与实现 实现SpringSecurity导入依赖包配置过滤器添加配置文件编码实现 在昨天实现了角色管理的增添查改与分页之后&#xff0c;在今天我们需要将不同的用户分类&#xff0c;以保证在用户是不同权限时&#xff0c;可以对所需的信息进…