【问题标题】:How do I use DOS interrupt 21h/AH=25h (set interrupt vector)?如何使用 DOS 中断 21h/AH=25h(设置中断向量)?
【发布时间】:2013-10-16 08:37:15
【问题描述】:

我提示用户输入:

mov ah, 0Ah
mov dx, OFFSET buffer
int 21h

我的作业告诉我 ctrl-c 应该“使用适当的错误消息中止程序”。

有人告诉我,每当调用或检测到 ctrl-c 时都会调用 int 23h。显然我可以通过 int 21h / ah=25h 注册我自己的中断处理程序。

但我不知道如何制作中断处理程序,也不知道它应该在我的代码中的什么位置。我们将不胜感激,在此先感谢您。

【问题讨论】:

标签: assembly x86 dos x86-16


【解决方案1】:

执行以下操作来编写您的自定义中断处理程序

SettingIntVector:
     mov ah,25h      ;Here set your ah register for calling Interrupt vector
     mov al,22h      ;Your Interrupt Address
     mov dx,IntHandlerCode   ;Interrupt Handler
     int 21h                 ;Dos Interrupt 



 IntHandlerCode:
    mov ah,9
    mov dx, offset our_text
     mov ah,9
    int 21h   
    iret

our_text db "new Interrupt Handler... $"

我希望这有助于弄清楚这些东西是如何工作的。这个中断只需在屏幕上写“新的中断处理程序”

【讨论】:

  • 中断处理程序不需要恢复它修改的任何寄存器吗?或者int 21h API 是否在您的代码周围放置了一个包装器来为您执行此操作? (我猜它没有,否则你会返回到一些恢复 regs 的 DOS 代码,使用 ret 而不是 iret。或者如果你返回 DOS 而不是这里发生特权切换到您自己的代码?)根据 Martin 的回答,您的函数地址直接进入 IDT,因此您应该需要保存/恢复 regs。
  • @PeterCordes 它本质上是一个 API 入口点,或者更准确地说是一个 API 回调。在这种情况下,中断需要保留所有寄存器,除了用作返回值的进位标志。由于这段代码保留了进位标志,中断的 MS-DOS 函数被重新启动。这个处理程序的另一个问题是,如果在输出消息时按下 CTRL-C,它可能会被递归调用。需要注意的是DS作为handler的段,所以CS == DS必须为真。最后它改变了错误的向量,22h 而不是 23h。
  • @RossRidge:谢谢!有趣的是,看看非多任务操作系统如何处理这样的事情。回调真的应该使用iret,而不仅仅是一个近或远的回报?因为iret 从堆栈中恢复EFLAGS,这与您将CF 作为返回值的一部分的描述相冲突。或者回调是否可以选择返回 iretret far 2 以弹出标志而不恢复它们? (我只能看到iretret far 之间的实模式差异)。此外,看起来您的评论会对 OP 的问题做出可靠的回答:P
  • @PeterCordes 在这种情况下,处理程序可以使用 IRET、RETF 2 或 RETF。后者之所以有效,是因为 MS-DOS 在调用后检查 SP 以查看它弹出的内容。
【解决方案2】:

据我所知,函数 ah=25h 只是将中断向量写入中断向量表。

此表位于地址 0000:0000,包含指向中断的段:偏移量指针。

这意味着:函数 25h 将简单地将段(CS 的值)写入地址 0000:008E,并将偏移量(中断处理程序的地址)写入 0000:008C。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-23
    • 2023-03-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多