簡體   English   中英

匯編中的STI、RET、IRET指令有什么區別

[英]What is the difference between the instructions STI, RET and IRET in assembly

所以在匯編中,STI 啟用中斷,RET 從堆棧中取出一個數字並將其放入 IP 並在指令 [IP] 處恢復執行。 IRET 做這兩個,對吧? 那為什么我不能使用 STI 和 RET 來代替呢? 或者我可以一直使用 IRET 嗎?

iret很復雜——它的行為取決於很多事情(CPU 模式、返回信息等),在某些情況下,它可能會執行完整的硬件任務切換(更改每個通用寄存器和 CR3/虛擬地址空間)。

最簡單的iret將從iret加載 CS、IP/EIP/RIP 和 FLAGS/EFLAGS; 但通常它也會加載 SS 和 SP/ESP/RSP; 並且所有段寄存器加載(CS、SS)都會導致 GDT 或 LDT 查找和保護檢查(這會增加開銷)。

另請注意,加載 FLAGS/EFLAGS 會恢復其先前的值。 如果在中斷處理程序啟動之前禁用可屏蔽中斷(這對於軟件中斷和異常是可能的),那么保存在堆棧中的 FLAGS/EFLAGS 將具有“中斷標志清除”並且IRET將恢復“中斷標志清除”和不會導致“中斷標志設置”。

ret僅從堆棧中加載 IP/EIP/RIP。 它不加載 CS 或 FLAGS/EFLAGS。

sti不加載 FLAGS/EFLAGS 並且只設置一位,這包括不恢復所有其他標志(例如進位、溢出等)。 這可能是一個非常重要的區別(例如,您不希望 IRQ 在未知/隨機時間丟棄算術標志並在各處導致不可預測的故障)。

這意味着sti then ret與(最簡單的) IRET非常不同——它的作用要少得多,而且行為(涉及 FLAGS/EFLAGS)也非常不同。

模擬iret行為的最接近的序列是popf (將 FLAGS/EFLAGS 恢復到其先前的值),然后是retf (加載 CS 和 IP/EIP/RIP); 並且這可能具有相同的復雜行為(例如可能會或可能不會導致權限級別更改,可能會或可能不會導致硬件任務切換)。

然而; 即使在這種“盡可能接近 IRET”的情況下,情況也不相同,因為 2 個單獨的指令是分開的 - 存在在popf但在retf之前發生 IRQ 的風險。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM