我了解呼叫門和陷阱門之間的區別。我想知道是否有人知道兩個門之間的速度有顯著差異。
如果將 DwordCount 欄位保留為 0(意味著沒有引數從外部堆疊復制到內部堆疊),速度是否也會有所不同?
uj5u.com熱心網友回復:
一般來說; 呼叫門只訪問 GDT,而陷阱門訪問 IDT,然后訪問 GDT。由于更差的區域性(TLB 未命中和高速快取未命中的可能性更高),這使得中斷陷阱門“在實踐中可能會更慢,而不管 CPU 的情況如何”。請注意,這相對重要,因為它們通常用于內核 API,您可以假設 CPU 在用戶空間中花費了足夠的時間來導致所有內核的東西“最近未使用”并從快取/TLB 中逐出。
對于特定的速度,很久以前我在 Pentium 4 上的回圈(快取所有內容)中對兩者進行了基準測驗,發現陷阱門比“沒有引數的呼叫門”慢了大約 15%,但不記得確切的成本回圈。我還沒有測驗過任何其他微拱。
我還希望使用引數會增加呼叫門的成本(由于從一個堆疊復制到另一個堆疊的成本)并且可能使其比陷阱門慢。
然而,“ int n”軟體中斷是 2 個位元組的代碼,而使用呼叫門(遠呼叫)的指令要大得多(7 個位元組?),部分原因是甚至沒有使用的偏移量。原始執行速度并不是影響性能的唯一因素——諸如從磁盤加載程式、動態鏈接、指令快取占用空間等也很重要。考慮到這一點,最快的策略可能同時支持兩者,并在很少使用的代碼(“執行一次”初始化代碼、錯誤處理)中使用軟體中斷,并在頻繁執行的代碼中使用呼叫門。
請注意,通常(對于內核 API)函式編號EAX由呼叫者放置在暫存器 ( ) 中;并且呼叫門處理程式或陷阱處理程式執行一些初步作業(設定呼叫約定等),然后執行“ call [table eax*4]”將控制轉移到請求的函式(或“無效函式編號”函式)。這意味著(假設引數在暫存器中傳遞)內核支持兩者(并為兩者使用相同的函式指標表)是微不足道的。更遠; 同樣的策略可以擴展到支持SYSCALLand SYSENTER,它們更快(如果 CPU 支持)并且可以在無效操作碼例外處理程式中模擬(如果 CPU 不支持)。
最后; 對于內核 API,絕對最快的方法是call [table eax*4]通過為每個特定函式設定呼叫門(或陷阱)來擺脫“ ”(這可能會導致 TLB 和快取未命中以及分支預測錯誤)。這對SYSCALL或不起作用SYSENTER;對于陷阱,它受可用 IDT 條目數的限制;所以它真的只對呼叫門有意義。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/389799.html
