x86汇编中断服务程序能否调用另一个中断?

4

在自由支持x686环境下,我可以从中断服务例程内调用中断吗?

那么是否可以这样做:

isr:
    pusha
    call doSomething
    int 21h
    popa
iret

如果可能的话,这些嵌套中断是否有任何重大缺陷?
2个回答

3
虽然处理器对中断嵌套没有根本限制,但MS-DOS和BIOS服务不可重入。也就是说,在硬件中断期间调用它们通常不安全,因为当CPU正在执行MS-DOS或BIOS函数时可能会发生中断。
要在硬件中断服务例程中使用MS-DOS和BIOS服务,有许多步骤可以确保它们可以安全地使用。你需要做的事情相当复杂,其中包括监视InDos标志和挂钩其他中断,所以我只会指向汇编语言编程艺术中关于可重入性的部分。它做得非常好,涵盖了所有细节。
以下是该部分的摘录。这只是你可能需要做的一部分:
MS-DOS提供了一个特殊的一字节标志(InDOS),如果DOS当前活动,则该标志包含零,如果DOS已经处理应用程序请求,则包含非零值。通过测试InDOS标志,您的TSR可以确定是否可以安全地进行DOS调用。如果此标志为零,则始终可以进行DOS调用。如果此标志包含1,则可能无法进行DOS调用。MS-DOS提供了一个函数调用“获取InDOS标志地址”,返回InDOS标志的地址。要使用此功能,请将ah加载为34h并调用DOS。 DOS将在es:bx中返回InDOS标志的地址。如果保存此地址,则您的常驻程序将能够测试InDOS标志以查看DOS是否处于活动状态。
实际上,您应该测试两个标志,即InDOS标志和临界错误标志(criterr)。在从TSR调用DOS之前,这两个标志都应该包含零。在DOS版本3.1及更高版本中,关键错误标志出现在InDOS标志之前的字节中。
那么,如果这些标志都不是零,该怎么办?很容易说“嘿,当MS-DOS返回到用户程序时,请回来做这些事情”。但是你该如何做到这一点呢?例如,如果键盘中断激活了您的TSR,并且因为DOS正在忙碌而将控制权传递给真正的键盘处理程序,则不能指望您的TSR在DOS不再活动时会自动重新启动。
诀窍是将TSR修补到定时器中断以及键盘中断中。[...]

1
我认为这个答案偏离了主题,并引入了一些OP并没有问到的混淆层面(DOS,TSR等)。 - Ira Baxter
1
原帖提供了一个使用 int 21h 的示例,这是主要的 MS-DOS API 软件中断,然后问道“这些嵌套中断是否有任何重大缺陷”。他的具体示例在我上面的答案中描述了“缺陷”。更一般地说,你不能假设从“中断服务例程中调用中断”是安全的,因为你调用的中断可能已经被 ISR 中断,并且可能不可重入。 - Ross Ridge

2

中断调用类似于普通的call,但会压入标志位。而iret则是返回并弹出标志位。所以,是的,中断可以被递归调用。实际上,在另一个中断处理程序中调用中断很常见,因为硬件中断一直在系统上运行,除非你禁用它们。

硬件中断有进一步的限制,通常情况下在同一个处理程序内部正在处理时不会被调用。中断处理程序通过向中断控制器发出信号来通知硬件提供新的中断。


1
实际上,如果你愿意,你可以通过简单地将它推送到堆栈上的相同数据来模拟中断的效果。因此,一个中断可以由于硬件而中断另一个中断,但你可以造成相同的效果。难以做到的是模拟低优先级中断的动作。 - Ira Baxter

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接