基于 stack 的访问都将引发 stack 访问控制检查,对于 stack 的访问控制比一般的 data segment 访问检查要严格。
用简单的式子表达为:
if (RPL == DPL && CPL = DPL) { /* 通过检查,允许访问,加载 descriptor 进入 SS */
} else { /* 拒绝访问,引发 #GP 异常 */ goto do_#GP }
|
访问 stack 仅限于同级访问,RPL、CPL 以及 DPL 三者必须相等。即使 0 级代码也不能访问 3 级的 stack。
So:
TSS segment 中为每个权限级为了相应的 stack pointer,就是基于这个原因,TSS 中设了 0 ~ 2 级的 stack pointer,但不包括 3 级的 stack pointer,3 级的 stack pointer 要么存放在 SS & RSP 中,要么存放在 0 ~ 2 级的 stack 中。
若发生代码从 3 级切换到 0 级时,切换 stack 时,3 级的 stack pointer 被切换出来,存放在 0 级的 stack 中,而 0 级的 stack pointer 被加到 SS & RSP 中。0 级代码返回 3 级代码时,3 级 stack pointer 被重新加载到 SS & RSP 中。
通过检查的后续处理:
和 DS 一样,stack segment descriptor 会被加载到 SS 寄存器中,SS.RPL 就代表当前运行 stack 的权限级别。当发生 stack 切换时,SS.RPL 会被更新为新的权限级别。
7.1.2.1、 x64 下的 long mode 的 stack segment 访问 long mode 的兼容模式与 x86 原有的模式一致。 64 bit 模式下的 stack segment 访问与前述的 data segment 访问一样,processor 不会对 stack segment 的访问进行权限检查。
阅读(202) | 评论(0) | 转发(0) |