windows xp,ReactOS系统快速系统调用的实现
windows xp,ReactOS系统快速系统调用的实现
文章目录
快速系统调用
从奔腾2开始就增设了两条指令和三个寄存器来支持“快速系统调用”sysenter,sysexit指令,MSR寄存器,这样就实现比较轻便和搞笑的系统调用
在快速系统调用时,用户空间的“int 0x2e"自陷指令大体上为一条sysenter指令锁替代,但是sysenter指令不同于int 指令或者call指令。sysexit指令也不同于iret,ret指令,这两条指令并不涉及 到堆栈的操作。而是依赖一组MSR寄存器。
进入R0
当执行sysenter指令时,CPU进入R0,并且:
1,把寄存器SYSTEMER_CS_MSR的内容复制到段寄存器CS中。
2,把寄存器SYSTEMER_EIP_MSR的内容复制到段寄存器EIP中。
3,把(寄存器SYSTEMER_CS_MSR的内容+8)复制到段寄存器SS中。
4,把寄存器SYSTEMER_ESP_MSR的内容复制到段寄存器ESP中。
这样,只要预先设置好三个MSR寄存器的内容,cpu在指向sysenter指令病会进入R0,并预定的地址开始执行程序, 同时开始使用系统空间的堆栈,而不像通过自陷指令进入系统空间那样要执行那么多的操作,效率提高了。
但是此时CPU不想在执行子限制了时那样自动把用户空间的堆栈指针保存在系统空间堆栈上,甚至也不讲返回地址压入堆栈,所有如果需要就要有对象的程序来完成操作。尽管如此,快速系统调用的效率还是要搞很多,因为至少不需要从中断向量表获取程序入口的位置了。
我们看MSR寄存器中的内容到底是啥子
ULONG_PTR
NTAPI
KiLoadFastSyscallMachineSpecificRegisters(IN ULONG_PTR Context)
{
/* Set CS and ESP */
Ke386Wrmsr(0x174, KGDT_R0_CODE, 0);
Ke386Wrmsr(0x175, (ULONG)KeGetCurrentPrcb()->DpcStack, 0);
/* Set LSTAR */
Ke386Wrmsr(0x176, (ULONG)KiFastCallEntry, 0);