中断的概念

软件中断

软件中断又简称内中断,它通常由三种情况引起。

由中断指令INT n引起

CPU执行完一条INT n指令后,会立即产生中断,并且调用系统中相应的中断处理子程序来完成中断功能,n指出中断类型。

由于CPU的某些错误引起

(1)除法错中断(中断类型号 0)
执行除法指令时,若发现除数为0或超过了寄存器所能表达的范围,则立即产生一个类型为0的中断。
(2)溢出中断(中断类型号 4)
若溢出标志OF置1,由中断指令INTO来处理发生溢出的中断操作;若OF为0,则INTO指令不产生中断,CPU继续运行原程序。

为调试程序(DEBUG)设置的中断

(1)单步中断(中断类型号 1)
在DEBUG下执行T命令(或P命令)时,陷阱标志TF置为1,CPU自动产生类型为1的单步中断。产生单步中断时,CPU自动地将PSW、CS和IP的内容入栈保存,然后清除TF、IF。
(2)断点中断(中断类型号 3)
断点中断也是供DEBUG调试程序使用的。在调试程序时,当CPU执行到断点时便产生中断,这时显示出各寄存器及相关标志,可以查看寄存器或存储单元的内容。设置断点实际上是把一条断点指令INT 3插入到程序中,CPU每执行到断点处的INT 3指令,便产生一个中断。

  • 在内中断中,INT n指令和INTO指令产生的中断,以及除法错中断都不能被禁止,并且比任何外部中断的优先权都高。

硬件中断

硬件中断是由输入输出外设产生的中断请求引起的中断,又称为外部中断。80X86系统的硬件中断分为可屏蔽中断和不可屏蔽中断两大类。两者都是通过CPU的引脚引入中断请求信号的。

不可屏蔽中断

不可屏蔽中断请求信号接到CPU的NMI引脚上,主要是发生电源故障、奇偶校验错、I/O通道校验错等紧急情况时系统自动产生的。NMI不可屏蔽中断的中断类型号为2。

可屏蔽中断

可屏蔽中断是键盘、显示器、打印机、磁盘、串行口/并行口等外设发出的。由于可屏蔽中断种类较多,各种处理要求不一样,因此系统专门用8259A中断控制器来管理这些中断。

中断类型与中断向量

中断类型

80X86系统提供了256个中断类型(可用1字节表示),类型号为0~FFH。
中断类型代表了不同的中断源,而系统对中断类型的分配按照一定的规则划分。例如0号~4号为内中断,8号~0FH号为8259A中断控制器控制的8个硬件中断,10H~1AH号为BIOS基本输入输出系统专用,21H号为DOS中断系统功能调用等。
在256个中断类型中,系统只占用了一部分,还有一些保留的供以后扩展时使用。

中断向量

与每个中断类型相对应的中断处理子程序都有一个入口地址,即该中断子程序第1条指令的逻辑地址,该入口地址称为中断向量。
中断向量存放在系统的中断向量表中。中断向量由段地址和偏移地址构成,占用4个字节单元 。将中断类型号乘以4,找到对应的存储单元就可取出中断向量。

中断优先级

优先级分类如下:
内部中断(优先级最高)
非屏蔽中断(NMI)
可屏蔽中断(INTR)
单步中断(优先级最低)

中断过程

中断响应条件

满足以下4条,CPU才可以响应中断:
(1) 当前的指令周期结束;
(2) 采样到有效的中断请求信号;
(3) 如果是可屏蔽中断请求INTR,检查中断允许标志IF是否为1,即中断开放;
(4) CPU正在执行的程序不是中断服务程序,或者是中断优先级较低的中断服务程序。

有几种特殊情况CPU不能响应中断:
(1) 当执行到STI指令时,CPU不会马上响应中断。STI指令是开中断指令,要求在开放中断后再执行后续的一条指令后才能响应中断;
(2) IRET指令是中断子程序返回指令,它也要求再执行一条后续指令后才能响应中断。这样做的目的是保护系统能够正常运行;
(3)当执行MOV SS,AX指令,即向SS段寄存器传送数据时,即使发生了中断,CPU也不会响应;直到本条执行完后,接着再执行一条指令才响应中断。

中断处理

CPU响应中断之后,就转入中断处理子程序执行。中断处理子程序的编写与子程序类似,也要保护现场和恢复现场。中断处理的内容和中断类型的设置要求相同。
中断也允许嵌套。由于中断类型被设置了优先级,如果新发生的中断级别高于现在正在处理的中断,那么CPU中止现有中断处理程序,转去执行较高级别的中断处理程序。

中断返回

中断子程序的最后一条汇编指令必须是IRET中断返回指令。该指令的作用是将保存在堆栈中断点的偏移地址和段地址弹出,修改IP和CS寄存器;再把保存在堆栈中的PSW各标志位弹到FLAGS寄存器中,然后返回到被中断的程序去继续执行。

中断过程和子程序调用CALL指令和RET返回指令过程类似,但它们也有不同之处。
中断的特点:
(1)除了用堆栈保存断点的返回地址CS:IP之外,还保存了标志寄存器PSW的内容;
(2)在中断发生时,CPU自动清除了IF位和TF位。使执行中断处理过程中,避免再次发生外部中断的干扰。
(3)中断返回 指令IRET执行时,除了将断点地址从堆栈中弹出,还将栈中保存的标志位放入标志寄存器FLAGS。

中断设置

设置中断向量

将在DS:DX中的中断向量写入中断向量表中。
格式:

AH=25H 
AL=中断类型号
DS:DX=中断向量
INT 21H

取中断向量

从中断向量表中取出中断向量放入ES:BX中。
格式:

AH=35H
AL=中断类型号
INT 21H

中断驻留

中断驻留是一种特殊的退出程序功能,它在退出前保留程序占用的内存,使这些内存单元不被其它程序覆盖或占用。

AH=31H
AL=0
DX=驻留程序长度
INT 21H

AL=0表示返回码

示例

;9-1.asm  笑脸中断程序INT 60H,采用驻留。
.model small
.stack
.code
mess1 db 0ah,0dh,'enter interrupt!',0ah,0dh,'$'
mess2 db 'exit interrupt!$'
mess3 db 0ah,0dh,'Continue or Quit(c/q)?$'
;主程序
main proc far
start:
mov ax,@code
mov ds,ax

;设置新的中断向量
mov dx,offset smile_face ;获得中断子程序偏移地址
mov ax,seg smile_face ;获得中断子程序段地址
mov ds,ax
mov al,60h ;将现在的60H号
mov ah,25h ;中断向量放入中断向量表中
int 21h

;应用部分
conti:
mov dx,offset mess1 ;显示提示1
mov ah,9
int 21h
int 60h ;触发60H号中断,进入中断子程序执行
mov dx,offset mess2 ;显示提示2
mov ah,9
int 21h
mov dx,offset mess3 ;显示提示3
mov ah,9
int 21h
mov ah,1 ;键入选择
int 21h
cmp al,'c'
je conti

;将中断子程序驻留内存
mov al,0
mov ah,31h ;驻留功能
mov dx,smiend-smigin+16 ; 中断子程序长度
int 21h
main endp ;主程序结束

;中断子程序
smile_face proc far
smigin:
sti ;开中断
mov cx,10
leng:
mov dl,01h ;笑脸符号
mov ah,2
int 21h
loop leng

mov dl,0dh ;回车换行
int 21h
mov dl,0ah
int 21h
cli ;关中断
Iret ;中断返回
smiend:nop
smile_face endp

end start

BIOS中断

  • BIOS主要有几部分:
    系统硬件检测和初始化程序;
    内中断的中断处理程序;
    硬件中断的中断处理程序;
    I/O设备及接口控制等功能模块。

屏幕及光标控制 INT 10H

光标控制

(1)光标大小设置

AH=01H
CH=光标开始行
CL=光标结束行
INT 10H

(2)设置光标位置

AH=02H
DH=行号
DL=列号
BH=页号
INT 10H

(3)读光标位置

AH=03H
BH=页号
INT 10H

返回值:DH=行号,DL=列号,CX=光标大小

卷屏、清屏、开窗口

(1)选择显示页
AH=05H
AL=页号
INT 10H
(2)屏幕开窗口

AH=06H
AL=0
BH=窗口颜色属性
CH=左上角行号
CL=左上角列号
DH=右下角行号
DL=右下角列号
INT 10H

(3)屏幕上卷

AH=06H
AL=上卷行数
BH=卷入行属性
CH=左上角行号
CL=左上角列号
DH=右下角行号
DL=右下角列号
INT 10H

(4)屏幕下卷
AH=07H
其余同屏幕上卷

字符读与显示

(1)读当前光标处字符和属性
格式: AH=08H
BH=页号
INT 10H
返回值:AH=属性,AL=字符
(2)显示多个带属性的相同字符
格式: AH=09H
BH=页号
CX=字符重复个数
AL=字符
BL=属性
INT 10H
(3)显示多个无属性的相同字符
格式:AH=0AH
BH=页号
CX=字符重复个数
AL=字符
INT 10H
(4)显示一个字符
格式:AH=0EH
AL=字符
INT 10H
(5)显示字符串
格式:AH=13H
ES:BP=字符串地址
CX=字符串长度
BH=页号
AL=0,BL=属性,光标返回开始处
AL=1,BL=属性,光标跟随字符移动
AL=2,要求字符和属性一起定义,光标返回开始处
AL=3,字符和属性一起定义,光标跟随字符移动
INT 10H

键盘中断 INT 16H

8086系统对键盘的处理分为两个层次。硬件接口处理(9号键盘中断)和BIOS系统键盘处理(INT 16H)。

硬件接口处理

当键盘上的按键按下时,通过8259A中断控制器向CPU发出9号硬件中断请求。如果此时中断允许标志位IF为1,CPU会响应此中断,转到9号硬件键盘中断处理程序去执行。

BIOS系统键盘处理

(1)从键盘读出一个字符
格式:AH=00H
INT 16H
返回值:AL=字符ASCII码,AH=扫描码。
功能:从键盘缓冲区队首取出字符送入AX,同时缓冲区后续字符前移。
(2)判断并读出键盘字符
格式:AH=01H
INT 16H
返回值:ZF=0,AL=字符ASCII码,AH=扫描码;ZF=1,缓冲区为空。
功能:可从ZF值判断键盘缓冲区中是否有按键字符。
(3)读取键盘状态
格式:AH=02H
INT 16H
返回值:AL=键盘状态字节。
功能:读取控制键等特殊功能键的状态。
(4)软件模拟按键
格式:AH=05H
CL=键的ASCII码
CH=键的扫描码
INT 16H
功能:在键盘缓冲区队尾单元写入一个字符,模拟按键按下。

时钟中断 INT 1AH

(1)读取时钟计数器当前值
格式:AH=00H
INT 1AH
返回值:CX=计数值高字,DX=计数值低字。
(2)设置时钟计数器
格式:AH=01H
CX=计数值高字
DX=计数值低字
INT 1AH
注意:此项操作会修改系统时钟。

DOS中断

显示功能调用

显示一个字符

格式1:AH=02H
DL=字符
INT 21H
功能:屏幕上显示一个字符,光标跟随字符移动。检验DL是否为Ctrl_Break。
格式2:AH=06H
DL=字符
INT 21H
功能:屏幕上显示一个字符,光标跟随字符移动。不检验Ctrl_Break。

显示一串字符

格式:AH=09H
DS:DX=字符串地址
INT 21H
功能:屏幕上显示一串字符,光标跟随字符移动。要求字符串必须以$结尾。

打印一个字符

格式:AH=05H
DL=字符
INT 21H
功能:把一个字符送到打印机上打印出来。

键盘功能调用

键入一个字符并回显

格式:AH=01H
INT 21H
返回值:AL=字符的ASCII码。

键入一个字符不回显

格式1:AH=07H
INT 21H
返回值:AL=字符的ASCII码。不检验键入的字符是否为Ctrl_Break。
格式2:AH=08H
INT 21H
返回值:AL=字符的ASCII码。对键入的字符检验是否为Ctrl_Break。

键入一串字符保存到缓冲区

格式:AH=0AH
DS:DX=字节缓冲区首址
INT 21H
要求:缓冲区的第1个字节单元为允许输入的最大字符数,第2个单元为实际键入个数,从第3个单元开始存放键入字符。

读键盘状态

格式:AH=0BH
INT 21H
返回值:有键入,AL=0FFH;无键入,AL=00H。

清除键盘缓冲区并调用

格式:AH=0CH
AL=功能号
INT 21H
功能:清除键盘缓冲区的同时,调用键盘输入功能(1、7、8、10功能号)。使用此功能可以在输入一个字符之前将以前输入的字符从缓冲区清除。

日期、时间功能调用

读取系统日期

格式:AH=2AH
INT 21H
返回值:CX=年,DH=月,DL=日,AL=星期。日期值为十六进制数。

设置系统日期

格式:AH=2BH
CX=年
DH=月
DL=日
AL=星期
INT 21H
返回值:AL=00,设置成功;AL=0FFH,无效。

读取系统时间

格式:AH=2CH
INT 21H
返回值:CH=小时(0~23),CL=分(0~59),DH=秒(0~59),DL=百分秒(0~99)。

设置系统时间

格式:AH=2DH
CH=小时(0~23)
CL=分(0~59)
DH=秒(0~59)
DL=百分秒(0~99)
INT 21H
返回值:AL=00,设置成功;AL=0FFH,无效。