首页 > 解决方案 > 在“sti”之后执行“ret”不会开始中断

问题描述

我正在开发一个微内核。在我的内核中,有一个启用外部中断的函数。但它不起作用。然后我意识到导致问题的指令是 asti后跟ret. 英特尔软件开发人员手册说:

如果 IF = 0,可屏蔽硬件中断在 STI 执行后的指令边界上保持禁止。(提供此指令的延迟效果是为了允许在从过程或子程序返回之前启用中断。例如,如果 STI 指令后跟 RET 指令,则允许在识别外部中断之前执行 RET 指令. 如果在执行 STI 之后立即执行 CLI,则无法识别中断。)在传递另一个事件(例如,异常)或执行下一条指令后,禁止结束。

所以中断应该在ret指令之后启用,但这不会发生。IF in eflags in set,但没有外部中断。如果我在andnop之间放一条指令,一切正常。stiret

最小的可重现示例:

        asm volatile ("call 1f;"
                      "jmp 2f;"
                      "1:"
                      "sti;"
//                      "nop;"
                      "ret;"
                      "2:");

取消注释,nop将启用中断。此外,如果我在上面放置以下行之一,则中断工作:

        asm volatile ("jecxz 1f; 1:");
        asm volatile ("pushf; popf");

注意:我使用 QEMU 来运行我的内核。

标签: assemblyx86interruptqemu

解决方案


推荐阅读