在使用 iret 指令从中断服务程序(ISR)返回之前,我们必须向第一个可编程中断发送带有“mov al,020h”+“out 20h,al”的“中断结束”信号(EOI)控制器(PIC 1;8259A)。
另一种方法是跳转到旧的 ISR,而不是发送 EOI,然后返回 iret。
;---------------
Ralf Browns x86/MSDOS 中断列表 (RBIL)
http://www.pobox.com/~ralf
http://www.pobox.com/~ralf/files.html
ftp://ftp.cs.cmu.edu/ afs/cs.cmu.edu/user/ralf/pub/
RBIL->inter61d.zip->PORTS.A
----------P0020003F-------------------------
PORT 0020 -003F - PIC 1 - 可编程中断控制器 (8259A)
另见:端口 00A0h-00AFh"PIC 2",INT 08"IRQ0",INT 0F"IRQ7"
....有关详细信息,请查看 RBIL..
;------------
为了成为 TSR,我们必须使用 INT 27h 来终止我们的应用程序的 ISR 部分保持驻留。
RBIL->inter61c.zip->INTERRUP.K
--------D-27---------------------------- -----
INT 27 - DOS 1+ - TERMINATE AND STAY RESIDENT
DX = 保持驻留的字节数(最大 FFF0h)
CS = PSP 段
返回:从不
注意:这是一个过时的调用
INT 22、INT 23 和从 PSP 恢复的 INT 24
不会关闭任何打开的文件DOS 2.x
将保持驻留的最小字节数为 110h,
对于 DOS 3.0+ 为 60h;DOS 1.x 没有最低要求,它
在 COMMAND.COM 而不是 DOS 内核中实现此服务
另见:INT 21/AH=31h
;----------
它认为在我们的 ISR 中使用软件中断调用不是一个好主意。所以我更喜欢直接写入视频内存,例如在屏幕的右上角写一些数字以显示当前时间。
;------
设置和获取中断向量:
RBIL->inter61b.zip->INTERRUP.F
--------D-2125---------------------------- ---
INT 21 - DOS 1+ - SET INTERRUPT VECTOR
AH = 25h
AL = 中断号
DS:DX -> 新的中断处理程序
注意:此函数优于直接修改中断
向量表,
一些 DOS 扩展程序在此设置了 API函数,因为它在 DR DOS 5.0-6.0 下
的保护模式下没有直接意义
,所以该函数不使用任何
DOS 内部堆栈,因此可以随时调用;但是,
在 Novell DOS 7.0 - DR-DOS 7.02 下,此函数不可重入。
自 1998/05/29 起,DR-DOS 7.03 不再使用任何内部堆栈和
更早地测试此函数,以允许
除了 IRET 帧之外仅使用两个字的最小堆栈使用,允许
从 INT 21h 函数调用它,特别是设备驱动程序。这
修复了 MCS SMB 客户端
Novell NetWare(新的 DOS 请求程序除外)监视
任何 INT 24 集的偏移量,如果等于启动时的值,则替换
其自己的处理程序以允许处理网络错误;这引入
了一个潜在的错误,即任何 INT 24 处理程序偏移量
恰好与 COMMAND.COM 相同的程序都不会安装其 INT 24
处理程序
另见:AX=2501h,AH=35h
--------D-2135 -------------------------------------------
INT 21 - DOS 2+ - GET INTERRUPT VECTOR
AH = 35h
AL = 中断号
返回:ES:BX -> 当前中断处理程序
注意:在 DR DOS 5.0+ 下,此函数不使用任何 DOS 内部
堆栈,因此可能随时调用
SeeAlso: AH=25h,AX=2503h
设置中断向量的另一种方法是写入向量本身的内存位置:
示例将 Timerinterrupt(8) 设置为我们的新 ISR,从标签“TIMER_INT”:
mov ax,0
mov ds,ax
cli
mov WORD PTR ds:[8*4],OFFSET TIMER_INT
mov WORD PTR ds:[8*4+2],cs
sti
短剑