中断过程描述:
- 取得中断内型码N;
- pushf
- TF=0,IF=0
- push CS
- push IP
- (IP)=(N*4),(CS)=(N*4+2)
CPU在收到中断信息后,如果处理该中断信息,就完成一个有硬件自动执行的中断过程,程序员无法改变这个过程中所要做的工作。似乎是想说上面的中断过程是由计算机硬件自己执行的,就这样理解。
中断处理程序的编写方法:
- 保存用到的寄存器
- 处理中断
- 恢复用到的寄存器
- 用iret指令返回
这边iret指令的功能用汇编语言描述为:
POP IP
POP CS
POPF
也就是iret执行完后,我们就不用再使用上面的三条指令(有点废话的感觉),或者还是感觉iret是有点多此一举了,鄙人之见……。
中断向量表是PC系统中最重要的内存区,只用来存放中断处理程序的入口地址,DOS系统和其他的应用程序不会随便的使用这段空间,这正是我们可以随便的利用中断向量表中的空闲单元来存放我们的程序,中断向量表的地址是0000:0000-0000:03ff 共1KB的空间,一般情况下,从0000:0200-0000:02ff的256个字节空间所对应的中断向量表都是空的,操作系统和其他的应用程序都不占用!
这边考虑一些问题,对于一个刚打开的CMD命令窗口,如果我们就在它上面先安装一个中断程序的话,然后再退出来,打开另外的一个CMD,再去触发中断程序,这样子,我们之前的中断程序就不存在了(没有运行到我们的中断程序,或者说是我们在内存中的中断程序就不是我们安装的中断程序了),这是为什么呢,我在java编程的时候也会遇到这样的问题,如何让它安装到我们的WINDOWS系统中呢,这边我想到了一个问题,如果是我们安装中断程序后,没有关掉CMD,时出现什么样的问题呢(想知道一下这是CMD本身的问题,还是WINDOWS 系统的问题)?试一下吧……
中断程序的安装代码HASM.ASM:
DATAS SEGMENT
;此处输入数据段代码
DATAS ENDS
STACKS SEGMENT
;此处输入堆栈段代码
STACKS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
MOV AX,DATAS
MOV DS,AX
;安装程序。先将中断程序指令放到指定位置,我们自己写一个中断程序随便在DOS
;下面显示一些字符,如HELLO ASM!程序指令段在此程序中的
;HELLO子程序中,我们将中断程序指令放到内存0000:0200--0000:02FF中
MOV SI,OFFSET HELLO
MOV DI,200H
MOV AX,CS
MOV DS,AX ;将要复制的程序指令的段地址放到DS中
CLD
MOV AX,0
MOV ES,AX ;将存放中断程序指令代码的段地址放到ES中
MOV CX,OFFSET ENDH- OFFSET HELLO ;设置要传送指令的长度
REP MOVSB ;复制指令
;设置中断向量表,我们将设置中断编码为7CH
MOV AX,0
MOV ES,AX
MOV WORD PTR ES:[7CH*4],0200H
MOV WORD PTR ES:[7CH*4+2],0
MOV AH,4CH
INT 21H
HELLO:
JMP SHORT STARTHELLO
DB 'HELLO ASM!'
STARTHELLO:
MOV AX,CS
MOV DS,AX
MOV SI,202H ;设定字符串的起始位移
MOV DI,160*12+80
MOV AX,0B800H
MOV ES,AX
MOV CX,10
S:
MOV AL,[SI]
MOV ES:[DI],AL
INC SI
ADD DI,2
LOOP S
IRET ;返回
ENDH:
NOP
CODES ENDS
END START
测试代码HASMTEST.ASM:
DATAS SEGMENT
DATAS ENDS
STACKS SEGMENT
STACKS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
MOV AX,DATAS
MOV DS,AX
;这段代码我么直接测试应用HASM.EXE安装的中断程序
INT 7CH
;S:
;JMP SHORT S
MOV AH,4CH
INT 21H
CODES ENDS
END START
好了,上面我们生成了两个文件HASM.EXE和HASMTEST.EXE文件,我们在同一个CMD下运行是可以的。这边我是想如何执行完HASM.EXE文件后,在执行HASMTEST.EXE文件后,可以顺利完成HASMTEST.EXE的执行……
但是结果不令人满意,现在发现一个问题了,原来我在执行HASM.EXE文件的滞后,代码中的MOV AX,4C00H INT 21H退出了程序,但是,是不是就是因为这样的退出程序的话,整个内存的原来的中断程序的代码就这样归附原位了呢,再看一下,把HASM.ASM中的MOV AX,4C00H INT 21H去掉,然后再重新执行EXE文件(修改完后,当然是重新生成新的EXE文件) ……
~~~糟糕,这样的话,要生成HASM.EXE文件都很难啊,因为如果这样的话,我们要直接复制的中断程序代码也会被执行,而其中运行到IRET指令的时候,麻烦也就出现了:
这是因为执行IRET指令时,都是出栈的事情,但是,我们在此代码文件中本来就没有入栈的相关操作,问题就这样让它自己不明不白的出现了,看来这个想法相当的危险,试一下其他的解决办法吧……
===============================================================
我们的中断程序代码中如果是有必要返回到原来的程序的时候,我们需要用IRET,但是像0号中断,我们是让它直接结束程序,或者这个根本就没有必要追究了……
19号终端例程本来在ROM中就已经是存在的,虽然DOS还是可以提供,但是这是不是已经没有意义了。