5.3.1 中断和中断源
所谓“中断”是指CPU在正常运行程序时,由于内、外部事件引起CPU暂时中止正在运行的程序,转而去执行请求CPU暂时中止的内、外部事件的服务程序,待该服务程序处理完毕后又返回到被中止的程序的过程。对某事件的处理实际上就是去执行一段例行程序,该程序被称为中断处理例行程序或中断处理子程序,简称为中断子程序。
能够向CPU发出中断请求的中断来源称为“中断源”。常见的中断源为:
(1)一般的输入/输出设备,如CRT终端、行式打印机等。
(2)数据通道,如磁带、磁盘等。
(3)实时时钟,如定时器芯片8253等的定时输出作为定时中断请求信号。
(4)故障信号,如电源掉电等。
(5)软件中断,如为调试程序而设置的中断源。
为讨论方便,本节以8086/8088系统的中断系统为例。
5.3.28086/8088的中断系统
1.中断源
8086/8088系统的中断源如图5-5所示。
图5-5 8086/8088中断源
2.中断分类
8086/8088系统的中断分为两大类:内中断和外中断。
(1)内(软)中断就是来自于CPU芯片内部的中断,如图5-5虚框内所示。内中断完全受程序控制,它是由CPU的状态改变或执行中断指令而产生的,它们的中断类型号或者是已经包含在指令中,或者是已经由CPU规定好。
具体可以分为以下几种:
①INTn指令。这类指令的中断类型号就是指令中的n,把n作为索引值,从中断向量表中得到相应的中断向量,便可转向中断处理子程序执行。这类指令是用户事前在程序中安排好的,当执行这条指令时就立即产生中断。例如常用的INT21H中断调用。INT指令的执行有些类似于CALL远程调用指令,但INT的执行和返回需要保存和恢复状态寄存器。
②除法错中断。该中断的类型号为0。在执行除法指令时,若发现被除或者商超出寄存器所能表示的范围,则立即产生一个0号中断,进入除法错中断处理子程序显示错误提示信息,然后返回操作系统。
③单步中断。该中断类型号为1。单步中断用于调试,它使单步过程成为能逐条指令地观察系统操作的一个“窗口”。例如,单步中断过程可以在每执行一条指令之后打印或显示寄存器的内容、指令指针值以及关键的存储器变量等。于是就能详细地跟踪一个程序的具体执行过程,以确定出问题的地方。
④断点中断。其中断类型号是3,格式为INT3。该指令一般可以处于程序中的任何位置。在断点处,停止正常的执行过程,以便执行某种类型的特殊处理。通常,在调试时把断点插入到程序的关键位置,以便显示寄存器、存储单元等内容。INT3是一条单字节指令,它使用户可以很方便地将断点“插入”到程序中的任何地方,也可以用来临时性地“修补”程序。
⑤溢出中断指令INTO。此中断的中断类型号是4。当溢出标志OF为0时INTO指令不产生中断,顺序执行下一条指令;当OF为1时则执行INTO转入4号中断处理子程序,显示一串出错信息,然后返回操作系统。
(2)外(硬)中断是来自CPU外部的中断,它是以完全随机的方式产生的。外中断可以分为不可屏蔽中断(NMI)和可屏蔽中断(INTR)。
①不可屏蔽中断(NMI)是为电源错、内存或I/O奇偶校验错等严重事件提供的,其中断类型号为2。当发生以上事件时,系统直接从中断向量表2×4的位置得到中断向量,转去执行中断处理子程序。
②可屏蔽中断(INTR)。从图5-5中看出,可屏蔽中断是来自外部设备的中断。这些中断源包括定时器、键盘、显示器、COM2、COM1、硬盘、软盘、打印机等常用设备,在8086/8088系统中其相应的中断类型号见图括号中内容所示。这些外设的中断请求通过8259A可编程中断控制器(PIC)的INT与CPU的INTR引脚相连。正如名称所示,8259A是可编程的中断控制芯片。8259A功能很强,编程的选择项也很多,其主要功能有以下3个方面:判断来自外设的中断请求输入信号IR是否有效。主要包括是否符合信号的电气规范以及是否被屏蔽。决定提出中断请求的设备中的哪一个优先级最高。因为一片8259A可管理8个硬件中断输入,但只有一个中断请求输出端INT,所以要进行中断优先级判断。CPU认可INT线上的中断请求信号时,8259A应将获得优先权的IR0~7所对应的中断类型号送到数据总线上。于是CPU接收数据总线上的中断类型号,然后同其他中断一样,通过该中断类型号从中断向量表中得到中断向量,转去执行相应的中断处理子程序。
3.中断优先级
如前所述,在8086/8088系统中有多个中断源。当同时有多个中断源向CPU发出中断时,CPU应该优先处理哪一个呢?这就涉及中断优先级的问题。8086/8088系统的优先级按下列次序安排:
4.中断嵌套
正在运行的中断处理程序又被其他中断源中断,这种情况称为中断嵌套。IBMPC机没有规定中断嵌套的深度,但在实际使用时应注意堆栈空间要足够大,以满足可能出现的中断嵌套的最大深度。
一旦进入中断处理,CPU就把当前的标志寄存器、CS和IP值依次压入堆栈,并清除TF和IF。在中断处理子程序中,可以用STI指令重新开放可屏蔽中断,使INTR线上的具有较高优先级的中断请求能中断当前这个中断过程(注意,直到STI之后的那条指令执行完后才会真正开放中断)。NMI线上的中断请求则始终能够中断任何可屏蔽中断处理过程。中断处理过程中出现的软件中断或处理机启动的中断也能中断该过程。必须注意,一个中断处理过程中不能再发生该过程正为之服务的中断。例如,试图在除法错中断处理过程中除以0,可能会陷入无穷尽的再入该过程的循环。
5.中断向量表
中断向量就是中断处理子程序的入口地址。在PC机中规定中断处理子程序为FAR型,每个中断向量占用4个字节,其中两个低字节为中断向量的偏移量部分,两个高字节为中断向量的段基址部分。系统用中断向量来定位中断子程序入口地址。
8086/8088系统安排了256类中断向量,就是有256个中断处理子程序,把这些中断向量按照中断类型号按由小到大的顺序排列,形成一个中断向量表,该表长为4×256= 1024字节,从内存的0000:0000地址开始存放,占用内存最低端的0~3FFH单元,这256个中断的安排详见表5-1。
表5-1 中断向量表
续表
续表
注:INT6CH是DOS(3.30版以上)为膝上机(Lap-top)提供的日时钟服务程序。
从表5-1中可以看出,256个中断向量分别分配给内部中断和外部中断。例如,01H号中断向量分配给了除法错中断源,09H号中断向量分配给外部键盘中断。有些中断向量的位置被系统保留,中断的服务程序则安排在ROMBIOS和DOS操作系统中。
6.中断类型号与中断指令
8086/8088系统共支持256类中断,相应编号为n,n的取值范围为0~255,把这些编号称为中断类型号。软中断靠程序中的软中断指令实现,软中断指令的语句形式为INTn。读者只要知道n对应中断服务功能,就可以调用中断服务了。具体如何使用INT指令,请参考第2章指令系统的有关内容。
5.3.3中断服务程序的设计
BIOS和DOS提供的中断服务程序为系统程序和应用程序的设计提供了极大方便。然而,如果要修改或扩充原中断服务程序的功能,或者配置新的设备时,就需要读者自行设计中断服务程序。对于中断服务程序的设计者来说,除了需要编写新的中断服务程序外,还需要确定这个中断服务程序与哪个中断类型号有关。除了可以使用中断向量表中保留的中断号外,如果要使用其他中断号,就必须保留原中断号内容,在原中断向量位置上设置新的中断入口地址,执行中断后,恢复原中断号的内容。
对于任何一种中断,只要CPU得到中断类型号(假设为n),就把它作为中断向量表的索引,从中断向量表的4n处得到中断向量,把其中的偏移量部分送IP、段基址部分送CS,然后把控制转到中断处理子程序执行。
中断向量表可能作为系统初始化的一部分在机器启动时已经装入了RAM,当中断机构使用其中的中断向量时它已存在。但有时用户希望使用系统未用的中断类型号扩充自己需要的中断功能,或者对原有中断处理功能进行改进,此时就需要把自己的中断向量写入中断向量表。用户自行设计程序从中断向量表中取出原有的中断向量保存,然后把自己的中断处理子程序入口地址按照所设计的中断类型号填入中断向量表的相应位置,以便以后能够从该位置得到所需的中断向量,从而转去执行用户自己设计的中断处理子程序。存取中断向量可以通过以下DOS系统功能调用实现。
1.设置(存)中断向量
调用参数:AH=25H,AL=要设置的中断类型号,DS:DX=要设置的中断服务程序的入口地址。
功能:把由AL指定的中断类型的中断向量放置在中断向量表中,其中中断向量由DS:DX给出。
2.取中断向量
调用参数:AH=35H,AL=要取出的中断类型号。
返回参数:ES:BX=取出的中断向量。
功能:从中断向量表中取出AL指定的中断类型的中断向量,并送到ES:BX中。
CPU处理中断实质上就是执行中断处理子程序,因此中断处理子程序的设计十分关键。另外,正确地把中断向量存入中断向量表也同样重要。下面是有关设计步骤。
(1)中断处理子程序的设计步骤:
①保存有关寄存器内容。
②若允许中断嵌套则开中断(STI)。
③处理中断。
④关中断(CLI)。
⑤发送中断结束命令(EOI)给8259A的中断命令寄存器。
⑥恢复寄存器内容。
⑦返回被中断的程序(IRET)。
其中第④、⑤步不是内中断和NMI的中断处理子程序所必需的。
(2)主程序的准备工作。为了在中断时能够执行到自己设计的中断处理子程序,主程序应做以下准备工作:
①保存原中断向量。
②设置新中断向量。
③8259A中断屏蔽寄存器的相应位清0。
④设置CPU的中断允许位(开中断)。
⑤主程序的其他工作。
⑥在主程序结束之前,恢复原中断向量。
第③、④步是为了响应可屏蔽中断请求所必需的。
(3)中断系统完成的工作。在主程序完成了上述一系列准备工作后,当有中断请求且满足一定条件时,CPU就可以在当前指令执行完成后响应中断,而对于STI、IRET、MOV和POP的目标操作数为段寄存器的指令时,则是在本条指令之后的那条指令执行完后响应,于是PC机的中断系统将自动完成:
①CPU接收外设的中断类型号。
②当前的FLAGS、CS、IP的内容保存入栈。
③清除IF、TF。
④根据中断类型号取出的中断向量送CS和IP。
第①步只针对可屏蔽中断。
【例5-6】编写40H中断服务程序,使其具有显示以“0”结尾字符串的功能。
DATASEGMENT
INTSEGDW?;用于保存原中断服务程序的段基地址
INTOFFDW?;用于保存原中断服务程序的偏移地址
MESSDB'WELCOMETOCCNU!',0DH,0AH,0;字符串,以“0”结尾
DATAENDS
CODESEGMENT
ASSUMECS:CODE,DS:DATA
START:MOVAX,DATA
MOVDS,AX
MOVAX,3540H;获取系统的原40H中断向量
INT21H
MOVINTSEG,ES;保存段基地址
MOVINTOFF,BX;保存偏移地址
PUSHDS
MOVDX,OFFSETNEW40H
MOVAX,SEG NEW40H
MOVDS,AX
MOVAX,2540H;设置本程序的40H中断向量
INT21H
POPDS
MOVDX,OFFSETMESS;设置入口参数DS:DX
INT40H;调用40H中断服务程序,显示字符串
MOVDX,INTOFF;恢复系统的原40H中断向量
MOVAX,INTSEG;先设置DX,后设置DS的入口地址
MOVDS,AX
MOVAX,2540H
INT21H
MOVAH,4CH;主程序返回DOS
INT21H
;40H内部中断服务程序;显示字符串;入口参数:DS:DX=缓冲区首地址
NEW40HPROC;定义过程
STI;开中断
PUSHAX;保护寄存器
PUSHBX
PUSHSI
MOVSI,DX
LP1:MOVAL,[SI];获取欲显示字符
CMPAL,0;判断为“0”结束
JZLP2
MOVBX,0;采用ROM-BIOS调用显示一个字符
MOVAH,0EH
INT10H
INCSI;显示下一个字符
JMPLP1
LP2:POPSI;恢复寄存器
POPBX
POPAX
IRET;中断返回
NEW40HENDP;中断服务程序结束
CODEENDS
ENDSTART
5.4DOS和BIOS功能调用
5.4.1DOS系统调用
DOS以INT21H提供了基本的文件管理、设备管理和内存管理等上百种功能,调用时由AH给出功能号,如本书第3章已介绍过DOS功能中的21H号子功能01H、02H、09H、0AH和4CH等。下面介绍一下其他功能调用。
1.终止程序
AH=31H:程序终止并驻留内存
调用参数:AL=返回码
DX=驻留内存的节数(1节=16字节)
功能:终止程序执行,但由DX所确定的一部分代码或数据仍留在内存中。
说明:调用31H与4CH功能时,均可由AL给出返回码,其含义由使用者定义,一般可以不用。返回码可由父进程通过INT21H的4DH功能得到,也可由DOS批处理文件的命令“IFERRORLEVEL”使用,以便判断程序的结束方式。31H功能主要用于设计驻留程序。
2.设置系统当前时间
AH=2BH:置日期
调用参数:CX:DX=日期
AH=2DH:置时间
调用参数:CX:DX=时间
【例5-7】设置系统的当前日期为2004年8月10日。
MOVCX,2004
MOVDH,8
MOVDL,10
MOVAH,2BH
INT21H
CMPAL,0
JNZERR
…
ERR:…
【例5-8】设置系统的当前时间为10点35分20秒。
MOVCH,10
MOVCL,35
MOVDH,20
MOVDL,0
MOVAH,2DH
INT21H
CMPAL,0
JNZERR
…
ERR:…
3.输入和输出字符
第3章已经介绍了调用DOS中断完成一个或一串字符的输入和输出,这里只举两个例子复习一下21号中断中1、2、9、10号子功能调用。
【例5-9】编写一个汇编语言程序,要求对键盘输入的小写字母用大写字母显示出来。
CODESEGMENT
ASSUMECS:CODE
START:MOVAH,01H
INT21H
CMPAL,'a'
JBEXIT
CMPAL,'z'
JAEXIT
SUBAL,20H
MOVDL,AL
MOVAH,02H
INT21H
EXIT:MOVAH,4CH
INT21H
CODEENDS
ENDSTART
【例5-10】编写一个汇编语言程序,要求在屏幕上显示一行提示信息,然后接收用户从键盘输入的信息,并将其存入内存缓冲区。
DATASEGMENT
BUFDB100;定义输入缓冲区
DB?
DB100DUP(?)
MESSDB'WHICHUNIVERSITY?'
DB'$';定义提示信息
DATAENDS
CODESEGMENT
ASSUMECS:CODE,DS:DATAS
TART:MOVAX,DATA
MOVDS,AX
DISPLAY:MOVDX,OFFSETMESS
MOVAH,09H
INT21H
KEYBD:MOVDX,OFFSETBUF
MOVAH,0AH
INT21H
MOVAH,4CH
INT21H
CODEENDS
ENDSTART
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。