过程返回时的特权级检查
我知道这是藏龙卧虎之地,来这里的有很多高手。
我这里有个关于80386cpu的问题,望不吝赐教。
当使用RET指令从被调用过程返回到调用过程时,如果是在不同特权级之间返回,cpu会比较被调用过程堆栈中存储的cs中的RPL(intel手册上如是说)和当前的cpl,用以确定是否需要特权级转换,我不明白的是为什么是rpl,而不是dpl,我觉得dpl才代表调用过程的特权级啊,检查rpl可以吗?希望有完整的解释,我是菜鸟!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
当然是 RPL 而不是 DPL。
RPL 是 selector 里面的域:selector.RPL
DPL 是 descriptor 里面的域:descriptor.DPL
这两个是不同的概念。
-------------------------------------------
但是,其实返回到程序的 CS.RPL 和 target-code segment descriptor's DPL 的值是一样的。
首先:
在 call 例程时,发现了权限的改变而导致 stack 切换。
在进入例程时的,processor 会依次将 SS 、esp 、CS 和 eip 入栈。
形成:
---------
SS
---------
esp
---------
CS
---------
eip <-------------- esp
---------
那么,栈里的 CS 是 caller(调用者)的 CS,caller 的 CS 里的 RPL。CS.RPL 也就是 code segment descriptor 里的 DPL 值,那是因为 processor 会用 code segment descriptor 里的 DPL 来更新 CS.selector.RPL
因此,CS.RPL 其实是等于 code segment descriptor's DPL
再者:
callee(被调用者)执行完后,将要 ret 到 caller 程序时,当时的 CPL = 0(设转到 0 级的前提下)。
processor 会依次先 pop 出 eip 和 CS。
那么,processor 会用 CPL (当前的 CPL)和 pop 出来的 CS 进行比较,即:
if (CPL == CS.RPL) { /* 相等时。。。 */
} else if (CPL < CS.RPL) { /* CPL < CS.RPL 时,表示,向低权限的代码返回 */
} else if ( CPL > CS.RPL) { /* CPL > CS.RPL 时,表示向高权限的代码返回 */
/* 这里将产生 #GP 异常,不允许向高权限代码返回 */
}
CPL 和 CS.RPL 相比较,其实和 caller(调用者)的 code segment descriptor's DPL 相比较,结果是一样的。
上面所说的只是本质上的一样,并不是说真正的 CPL 与 caller 的 code segment descriptor's DPL 相比较,因为,processor 处理器还没到 index code segment descriptor 这一步。
最后说一说 CPL、RPL 与 DPL 之间的关系:
CPL 是 processor 当前运行的权限级别。
CPL 就是 CS.RPL。(CS.selector.RPL)。
DPL 是 descriptor 里的元素。但是,当通过合法的检查后。DPL 会被加载到 CS.RPL
所以:在通过合法的检查后,并载到 CS 寄存器后。
CPL == RPL == DPL
---------------------------------------------
它们三者之间是相等的。
CPL 存储在 CS.selector.RPL 中,而 CS.selector.RPL 是由 code segment descriptor's DPL 加载而来的。
PS:
多点看看我置顶的贴子吧,《x86 & x64 沉思录》那里讲得很清楚。