SYSENTER/SYSEXIT指令

一、简介

        sysenter 指令可用于特权级 3 的用户代码调用特权级 0 的系统内核代码,而 SYSEXIT 指令则用于特权级 0 的系统代码返回用户空间中。sysenter 指令可以在 3,2,1 这三个特权级别调用(Linux 中只用到了特权级 3),而 SYSEXIT 指令只能从特权级 0 调用。

        sysenter/sysexit 和 int n/iret 指令的一个区别,那就是 sysenter/sysexit 指令并不成对,sysenter 指令并不会把 SYSEXIT 所需的返回地址压栈,sysexit 返回的地址并不一定是 sysenter 指令的下一个指令地址。


二、执行步骤

        sysenter指令执行前的准备工作

        1. 在调用SYSENTER指令进行系统调用时,需要在GDT中建立四个段,分别用来描述SYSENTER指令进入内核模式时使用的代码段(CS)和栈段(SS),以及SYSEXIT指令从内核模式返回用户模式时使用的代码段(CS)和栈段(SS)。这四个描述符在GDT表中的排列应该严格按照以上顺序,这样只要指定一个段描述符的位置便能计算出其他的。

        2. 设置下图中专门用于系统调用的MSR寄存器(使用WRMSR指令来设置这些寄存器):

        IA32_SYSENTER_CS 寄存器保存了内核代码段的描述符的index。

        IA32_SYSENTER_EIP 寄存器保存了内核里的快速系统调用分发例程的线性地址。

        IA32_SYSENTER_ESP 寄存器保存了内核里能获得本地TSS描述符的基地址。(只有这样,进入内核态后才能正确的设定esp为正确的值)

        sysenter指令执行步骤如下:

        1. 将IA32_SYSENTER_CS保存到CS中。

        2. 将IA32_SYSENTER_EIP保存到EIP中。

        3. 将IA32_SYSENTER_CS + 8 保存到SS中。

        4. 将IA32_SYSENTER_ESP保存到ESP寄存器中。

        5. 切换到ring 0级别。

        6. 如果EFLAGS中的VM标志被设定,那么清0该标志。

        7. 开始执行ring0代码。

 

        这sysexit指令执行前需要如下准备工作:

        设置EDX为ring3下要执行的指令的首地址。设置ECX为ring3下的栈指针。

        sysexit指令的执行步骤如下:

        1. 将IA32_SYSENTER_CS + 16保存到CS中。(ring3下代码段)

        2. 将EDX赋值给EIP

        3. 将IA32_SYSENTER_CS + 24保存到SS中。

        4. 将ECX赋值给ESP。

        5. 切换到ring3下继续执行ring3代码。

 

转载自: http://hi.baidu.com/taozpwater/item/98529bf681f9ebc6521c2677

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值