SYSENTER、SYSEXIT—快速系统调用
SYSENTER用來快速調用一個0層的系統過程。SYSENTER是SYSEXIT的同伴指令。該指令經過了優化,它可以使將由用戶代碼(運行在3層)向操作系統或執行程序(運行在0層)發起的系統調用發揮最大的性能。
?
在調用SYSENTER指令前,軟件必須通過下面的MSR寄存器,指定0層的代碼段和代碼指針,0層的堆棧段和堆棧指針:
1.?????? IA32_SYSENTER_CS:一個32位值。低16位是0層的代碼段的選擇子。該值同時用來計算0層的堆棧的選擇子。
2.?????? IA32_SYSENTER_EIP:包含一個32位的0層的代碼指針,指向第一條指令。
3.?????? IA32_SYSENTER_ESP:包含一個32位的0層的堆棧指針。
?
MSR寄存器可以通過指令RDMSR/WRMSR來進行讀寫。寄存器地址如下表。這些地址值在以后的intel 64和IA32處理器中是固定不變的。
| MSR | 地址 |
| IA32_SYSENTER_CS | 174H |
| IA32_SYSENTER_ESP | 175H |
| IA32_SYSENTER_EIP | 176H |
?
當執行SYSENTER,處理器會做下面的動作:
1.?????? 從IA32_SYSENTER_CS從取出段選擇子加載到CS中。
2.?????? 從IA32_SYSENTER_EIP取出指令指針放到EIP中
3.?????? 將IA32_SYSENTER_CS的值加上8,將其結果加載到SS中。
4.?????? 從IA32_SYSENTER_ESP取出堆棧指針放到ESP寄存器中
5.?????? 切換到0層。
6.?????? 若EFLAGS中VM標志已被置,則清除VM標志。
7.?????? 開始執行選擇的系統過程。
?
處理器不保存返回地址和調用過程的其他狀態信息。
?
SYSENTER指令總是轉移到DPL為0的保護模式下的代碼段。這條指令需要操作系統首先滿足下面的條件:
1.?????? 選擇的系統代碼段必須是一個平坦的、32位最大為4G的代碼段。此段必須是可執行的、可讀、已存取、非一致的。
2.?????? 選擇的系統堆棧段必須是一個平坦的、32位最大為4G的數據段。此段必須可讀寫、已存取、可向上擴展。
?
SYSENTER可在除實地址模式外所有其他模式下執行。
?
SYSENTER和SYSEXIT是同伴指令,但是它們并不像CALL/RET指令對。當執行SYSENTER時,處理器并不會為用戶代碼保存狀態信息。而且無論是SYSENTER還是SYSEXIT都不能通過堆棧傳遞參數。
?
為了能通過SYSENTER/SYSEXIT指令,使控制在3層用戶代碼和0層操作系統代碼之間相互轉移,必須滿足下面的條件:
1.?????? 0層的代碼段和0層堆棧段段以及3層的代碼段和3層堆棧段在GDT中必須連續。這樣就可以使處理器能從從SYSENTER_CS_MSR的值計算出其他的選擇子的值了。
?
2.?????? .若要返回調用過程,由用戶代碼執行的快速系統調用“樁”(STUB)例程(通常在共享庫或DLL中)必須保存返回地址以及處理器的狀態信息;當要返回至用戶代碼時,操作系統或者由SYSENTER調用的執行程序必須使用這些保存的地址和狀態信息。
?
SYSENTER和SYSEXIT指令是從Pentium II開始新加入到IA32位架構中來的。這兩個指令在處理器上是否有效要看CPUID指令返回的EDX寄存器中SEP標記(SYSENTER/SYSEXIT存在標記)是否置上。操作系統若要檢查SEP標記必須要同時檢查處理器族(family)和型號(model),這樣才能確保結果的準確性。例如:
?
| IF (CPUID SEP bit is set) IF (Family == 6) AND (Model < 3) AND (Stepping < 3) THEN Fast System Call NOT supported FI; ELSE Fast System Call is supported FI |
?
當CPUID指令在Penitum Pro(Model 1)上執行,雖然返回的SEP標志是置上的,但該處理器還是不支持SYSENTER/SYSEXIT指令的。
轉載于:https://www.cnblogs.com/snake-hand/archive/2013/06/06/3122839.html
總結
以上是生活随笔為你收集整理的SYSENTER、SYSEXIT—快速系统调用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 基于蚁群算法的岸桥作业顺序研究
- 下一篇: 【eoe教程】Android中自定义视图