【发布时间】:2014-08-30 16:22:24
【问题描述】:
我可以在独立的 x686 环境中从中断服务例程中调用中断吗?
所以可以做到以下几点:
isr:
pusha
call doSomething
int 21h
popa
iret
如果可能,那么这些嵌套中断是否有任何重大的塌陷?
【问题讨论】:
标签: assembly x86 interrupt interrupt-handling
我可以在独立的 x686 环境中从中断服务例程中调用中断吗?
所以可以做到以下几点:
isr:
pusha
call doSomething
int 21h
popa
iret
如果可能,那么这些嵌套中断是否有任何重大的塌陷?
【问题讨论】:
标签: assembly x86 interrupt interrupt-handling
虽然处理器对嵌套中断没有基本限制,但 MS-DOS 和 BIOS 服务是不可重入的。也就是说,在硬件中断期间调用它们通常是不安全的,因为中断可能在 CPU 已经执行 MS-DOS 或 BIOS 功能时发生。
要通过硬件中断服务例程使用 MS-DOS 和 BIOS 服务,您可以采取许多步骤来确保可以安全地使用它们。您需要做的事情相当复杂,除此之外,您还需要监控 InDos 标志并挂钩其他中断,所以我只会将您指向 The Art of Assembly Language Programming 中的 section on reentrency。它在涵盖所有细节方面做得很好。
这是该部分的摘录。这只是您可能需要做的一部分:
MS-DOS 提供了一个特殊的单字节标志 (InDOS),它包含一个零 如果 DOS 当前处于活动状态,如果 DOS 已经处于活动状态,则为非零值 处理申请请求。通过测试 InDOS 标志您的 TSR 可以确定它是否可以安全地进行 DOS 调用。如果此标志为零, 您可以随时拨打 DOS 电话。如果此标志包含一个,您可以 无法进行 DOS 调用。 MS-DOS 提供了一个函数调用,Get InDOS 标志地址,返回 InDOS 标志的地址。使用 这个函数,用 34h 加载 ah 并调用 DOS。 DOS 将返回 es:bx 中 InDOS 标志的地址。如果您保存此地址,您的 驻留程序将能够测试 InDOS 标志以查看 DOS 是否 活跃。
实际上,您应该测试两个标志,InDOS 标志和 严重错误标志(criterr)。这两个标志都应该包含零 在从 TSR 调用 DOS 之前。在 DOS 版本 3.1 及更高版本中, 严重错误标志出现在 InDOS 标志之前的字节中。
如果这些标志都不是零,你应该怎么做?这简单 足以说“嘿,稍后在 MS-DOS 时回来做这些事情 返回到用户程序。”但是你怎么做呢? 例如,如果键盘中断激活了您的 TSR 并且您通过 控制到真正的键盘处理程序,因为 DOS 很忙,你不能 预计您的 TSR 稍后会在 DOS 不存在时神奇地重新启动 活动时间更长。
诀窍是将您的 TSR 修补到定时器中断以及 键盘中断。 [...]
【讨论】:
int 21h 的示例,主MS-DOS API 的软件中断,然后询问“这些嵌套中断是否有任何重大的塌陷”。他的具体例子有我在上面的回答中描述的“陷入困境”。更一般地说,您不能假设“从中断服务例程中调用中断”是安全的,因为您调用的中断可能已被 ISR 中断并且可能不可重入。
中断调用类似于带有标志的常规call。 iret 所做的是返回并弹出标志。所以,是的,可以递归调用中断。实际上,由于硬件中断在系统上连续运行,所以在另一个中断处理程序中调用中断总是发生,当然除非你禁用它们。
硬件中断有进一步的限制,通常不会在同一个处理程序完成处理之前调用。中断处理程序通过向中断控制器发出信号来通知硬件提供新的中断。
【讨论】: