首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >汇编中的STI、RET和IRET指令有什么不同

汇编中的STI、RET和IRET指令有什么不同
EN

Stack Overflow用户
提问于 2019-12-31 10:45:37
回答 1查看 2.6K关注 0票数 0

因此,在汇编中,STI启用中断,而RET从堆栈中获取一个数字,并将其放入IP中,然后在指令IP处恢复执行。IRET同时做了这两件事,对吧?那么为什么我不能只使用STI和RET呢?或者我可以一直使用IRET吗?

EN

回答 1

Stack Overflow用户

发布于 2019-12-31 18:42:51

iret很复杂-它的行为取决于很多东西(CPU模式,返回信息等),在某些情况下,它可能会进行全硬件任务切换(更改每个通用寄存器和cr3/虚拟地址空间)。

最简单的iret将从堆栈加载CS、IP/EIP/RIP和FLAGS/EFLAGS;但通常它也会加载SS和SP/ESP/RSP;所有段寄存器加载(CS、SS)都会导致GDT或LDT查找和保护检查(这会增加开销)。

另请注意,加载FLAGS/EFLAGS会恢复其先前的值。如果在启动中断处理程序之前禁用可屏蔽中断(这对于软件中断和异常是可能的),则保存在堆栈上的标志/EFLAGS将具有“中断标志清除”,并且IRET将恢复“中断标志清除”,而不会导致“中断标志设置”。

ret仅从堆栈加载IP/EIP/RIP。它不加载CS或标志/EFLAGS。

sti不加载标志/EFLAGS,仅设置一位,这包括不恢复所有其他标志(例如进位、溢出等)。这可能是一个非常重要的区别(例如,你不希望IRQ在未知/随机时间丢弃算术标志,并在任何地方导致不可预测的失败)。

这意味着sti然后ret与(最简单的) IRET有很大的不同-它做的更少,行为(涉及标志/EFLAGS)也非常不同。

模拟iret行为的最接近的序列将是popf (用于将标志/EFLAGS恢复到其先前的值),然后是retf (用于加载CS和IP/EIP/RIP);并且这可以具有相同的复杂行为(例如,可以或可以不引起特权级别改变,可以或可以不引起硬件任务切换)。

然而,即使在这种“尽可能接近IRET”的情况下,它也是不同的,因为两个单独的指令是分开的-存在在popf之后但在retf之前出现IRQ的风险。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59539016

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档