huchen 发表于 2024-3-11 22:54

分析这下面代码的执行过程

mov ax,0x23
mov ds,ax
请问这个执行是会看CPL吗?
我的看法:首先把0x23写入ax寄存器,然后看段选择子,也就是ds的值是多少,拆分,得到RPL、TI、Index,然后算出在GDT表的位置,拆分得到DPL,比较谁的的权限高
有错的话还请指正一下


8003f00000000000`00000000(无效)00cf9b00`0000ffff(代码)
8003f01000cf9300`0000ffff(数据0)    00cffa00`0000ffff(代码)
8003f02000cff300`0000ffff(数据3)   80008b04`200020ab(系统)
8003f030ffc093df`f0000001(数据0)   0040f300`00000fff(数据3)
8003f0400000f200`0400ffff(数据3)    00000000`00000000(无效)
8003f05080008954`af000068(系统)80008954`af680068(系统)
8003f06000009302`2f40ffff(数据0)   0000920b`80003fff(数据0)
8003f070ff0092ff`700003ff(数据0)    80009a40`0000ffff(代码)

上面我写的是段描述符处于什么段,并且是能加载到几环的(后面的数字)我认为是看段描述符的DPL来决定的,不知是不是对的
还请大佬们指正一下

fortytwo 发表于 2024-3-12 13:11

gpt 4 128k 水一下

您的理解基本正确,但让我详细解释一下这个过程。
在x86架构的保护模式下,段寄存器(如DS)被用来存储段选择子(Segment Selector)。段选择子包含了几个部分:请求特权级(RPL)、表指示符(TI)和索引(Index)。当处理器执行如下指令时:
assembly
mov ax, 0x23
mov ds, ax
处理器会进行以下操作:
将立即数0x23加载到AX寄存器。
将AX寄存器的值加载到DS段寄存器,此时DS的值就是段选择子。
段选择子0x23的二进制表示为0010 0011,其中:
最低两位11是RPL,表示请求特权级为3。
第3位0是TI,表示该选择子指向全局描述符表(GDT)。
剩余的高位0010是索引,表示该选择子对应GDT中的第4个描述符(索引从0开始计数)。
接下来,处理器会使用这个索引去GDT中查找对应的段描述符。在您提供的GDT表中,索引为4的描述符是00cff3000000ffff`,这是一个数据段描述符,它的DPL(描述符特权级)是3,与RPL相同。
处理器会比较RPL和DPL:
如果RPL <= DPL,那么访问是允许的。
如果RPL > DPL,那么会产生一个特权级异常。
由于在这个例子中RPL和DPL都是3,所以加载这个段选择子到DS是允许的,不会产生特权级异常。
总结来说,您对段选择子的拆分和特权级比较的理解是正确的。当处理器加载段选择子到段寄存器时,它会检查段描述符中的DPL和段选择子中的RPL,以确保特权级别是允许的。在这个过程中,处理器不会直接查看当前的CPL(当前特权级),而是使用段选择子中的RPL和段描述符中的DPL进行比较。如果加载操作是在更高的特权级代码中执行的,CPL会在其他操作中发挥作用,特别是在访问受保护资源时。

huchen 发表于 2024-3-12 14:14

fortytwo 发表于 2024-3-12 13:11
gpt 4 128k 水一下

您的理解基本正确,但让我详细解释一下这个过程。


谢谢您,我大概懂了

frozenfish 发表于 2024-3-13 09:42

你这是在研究什么。操作系统?
页: [1]
查看完整版本: 分析这下面代码的执行过程