【问题标题】:Can an x86 assembly interrupt service routine call another interrupt?x86 汇编中断服务例程可以调用另一个中断吗?
【发布时间】:2014-08-30 16:22:24
【问题描述】:

我可以在独立的 x686 环境中从中断服务例程中调用中断吗?

所以可以做到以下几点:

isr:
    pusha
    call doSomething
    int 21h
    popa
iret

如果可能,那么这些嵌套中断是否有任何重大的塌陷?

【问题讨论】:

    标签: assembly x86 interrupt interrupt-handling


    【解决方案1】:

    虽然处理器对嵌套中断没有基本限制,但 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 修补到定时器中断以及 键盘中断。 [...]

    【讨论】:

    • 我认为这个答案偏离主题太远了,并且引入了 OP 没有询问的全新的混乱层(DOS、TSR、...)。
    • 原始发帖人给出了一个使用int 21h 的示例,主MS-DOS API 的软件中断,然后询问“这些嵌套中断是否有任何重大的塌陷”。他的具体例子有我在上面的回答中描述的“陷入困境”。更一般地说,您不能假设“从中断服务例程中调用中断”是安全的,因为您调用的中断可能已被 ISR 中断并且可能不可重入。
    【解决方案2】:

    中断调用类似于带有标志的常规calliret 所做的是返回并弹出标志。所以,是的,可以递归调用中断。实际上,由于硬件中断在系统上连续运行,所以在另一个中断处理程序中调用中断总是发生,当然除非你禁用它们。

    硬件中断有进一步的限制,通常不会在同一个处理程序完成处理之前调用。中断处理程序通过向中断控制器发出信号来通知硬件提供新的中断。

    【讨论】:

    • 事实上,如果您愿意,您可以通过简单地将其压入堆栈的相同数据来模拟中断的效果。因此,一个中断可以因为硬件而中断另一个,但是您可以产生相同的效果。难的是模拟低优先级中断的动作。
    猜你喜欢
    • 2020-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-07
    • 2022-08-11
    • 1970-01-01
    • 2015-06-21
    • 2012-11-06
    相关资源
    最近更新 更多