中断(interrupt)是CPU对外设呼叫或内部异常的一种响应
中断分为硬件中断和软件中断
硬件中断也叫外部中断、异步中断,它又分为两类:可屏蔽中断和不可屏蔽中断
软件中断也叫异常、内部中断、同步中断、内部不可屏蔽中断,软件中断时CPU根据某条指令或者标志寄存器中的某个标志而产生的。软件中断完全和硬件电路无关。典型的软件中断有:INT n指令中断、INTO(Interrupt if Overflow)指令中断、单步中断、除数为0中断
;设中断类型号为n,中断服务程序的名称为function,要求将function的地址置入中断矢量表中
;不考虑设置的新中断向量会覆盖中断向量表中原中断向量
;程序如下:
mov ax,0
mov es,ax ;es=0000H
mov di,n*4 ;es:di=0000:n*4
mov ax,offset function ;function的偏移地址送到ax
cld ;方向标志位DF清零。串操作中使变址寄存器di的地址自增
stosw ;function的IP偏移地址送到了中断矢量表中,同时DI自增2
mov ax,seg function ;function的段地址送到ax
stosw ;function的CS段地址送到了中断矢量表中,同时DI自增2
DOS功能调用:
- 设置中断矢量:DS:DX=中断服务程序入口地址,AL=中断类型号,AH=25H,用int 21H指令将中断服务程序入口地址置入到中断矢量表中
- 取得中断矢量:AL=中断类型号,AH=35H,用int 21H指令将对应中断类型号的中断向量从中断矢量表中取出,送到ES:BX
;设中断类型号为n,中断服务程序的名称为function,要求将function的地址置入中断矢量表中
;考虑设置的新中断向量会覆盖中断向量表中原中断向量,此时就要保存原中断向量
;程序如下:
;第一步:取得原中断向量,并入栈保护
mov al,n;
mov ah,35h
int 21h
push es
push bx
;第二步:设置新中断向量
mov ax seg function
mov ds,ax
mov dx, offset function
mov al,n
mov ah,25h
int 21h
;第三步:执行完自定义设置的中断程序后,就可恢复原中断矢量
pop dx
pop ds
mov al,n
mov ah,25h
int 21h
CPU在执行每条指令的最后一个时钟周期会对INTR信号进行采样,如果CPU的中断允许标志IF为1,并且INTR信号又为高电平,那么CPU就会在执行完当前指令后,响应中断请求,执行一个中断处理子程序
对于8086/8088CPU来讲,具体来说要依次做下面几件事:
注:如果是不可屏蔽中断或者软件中断,则跳过第1步,从第2步开始按次序执行到第7步。因为从NMI引脚进入的中断请求只能有一个,它必定对应中断类型2。至于软件中断,中断指令本身就为CPU提供了中断类型号
经过上述步骤后,CPU就开始执行中断处理子程序了。除去所处理的特定功能外,所有中断处理子程序都有着相同的结构模式,具体如下:
功能:在有多个中断源的系统中,像个管家般帮CPU接收外部的中断请求,并进行优先级控制和判断,选中当前优先级最高的中断请求,再将此请求送到CPU的INTR端
当CPU响应中断并进入中断处理子程序后,中断控制器仍管理着外部的中断请求,当某个外部中断请求的优先级高于当前正在处理的中断时,中断控制器会让此中断通过而到达CPU的INTR端,从而实现中断的嵌套,反之,对级别较低的中断则禁止
下图是中断控制器8259A内部的简要结构
8259A有7个可编程的8位寄存器,可分为两组
第一组4个,用来存放初始化命令字ICW(initialization command word),分别称为ICW1—ICW4。初始化命令字往往是计算机系统启动时初始化程序设置的,一旦设定,一般在系统工作过程中不再改变。
第二组3个,用来存放操作命令字OCW(operation command word),分别称为OCW1—OCW3。操作命令字是由应用程序设定的,用来对中断处理过程作动态控制,操作命令字可被多次设置。
在全嵌套方式中,从IR0进入的中断优先级最高,从IR7进入的中断优先级最低。相对应的,中断服务寄存器ISR中IR7—IR0这8位从左到右优先级从低到高,这就是中断优先级裁决电路的裁决依据。对8259A进行初始化后,如果不再写入任何操作命令字,8259A就处于全嵌套工作方式
与全嵌套方式只有一个差别:可以响应同级中断请求。而在全嵌套方式中,只有当更高级的中断请求来到时,才会进行嵌套,当同级中断请求来到时,不会进行响应。
中断服务寄存器ISR中IR7—IR0优先级排序是在发生变化的。某个端口的中断请求受到服务后,它的优先级自动降为最低。比如处理完IR4后,IR4就是最低优先级,IR5就是最高优先级,然后依次为IR6、IR7、IR0、IR1……注意:一开始的最低优先级是IR7
与优先级自动循环方式只有一个差别:一开始的最低优先级是编程确定的。
8259A的每个中断请求输入端,都可通过设置IMR的对应屏蔽位(置1表示屏蔽)而被屏蔽,从而使对应的中断请求不能从8259A送到CPU
仅屏蔽当前正在处理的这级中断本身,允许高级或低级的中断进入。需先通过OCW3使8259A工作于特殊屏蔽方式,再用OCW1使本级中断的屏蔽寄存器的相应位置1,仅屏蔽本身。例如:系统处于特殊屏蔽方式,正在处理IR3中断,又用OCW3命令屏蔽掉IR3中断,则使IM3=1,IS3=0,这时,IR0—IR2和IR4—IR7中断均可进入
当一个中断请求得到响应时,8259A会在中断服务寄存器ISR将相应位置1,这是为了给中断裁决电路提供依据,当中断处理程序结束时,必须使ISR中相应位清0,否则中断裁决电路的判据就不正确。而使ISn位清0的动作就是中断结束处理
场景:只能用于系统中只有一片8259A且多个中断不会嵌套的情况
设置方法:对8259A初始化时,使初始化命令字ICW4的AEOI位置1
当第二个中断响应脉冲 INTA ‾ \overline{\text{INTA}} INTA送到8259A后,8259A就会自动将当前中断服务寄存器中的对应位ISn置0,这样,尽管系统还正在进行着中断服务,但对8259A来说,当前中断服务寄存器中却没有对应位做指示,所以,就好像已经结束了中断服务一样
场景:用在全嵌套方式的情况下
设置方法:在程序中往8259A的偶地址口输出一个操作命令字OCW2,并使得OCW2中EOI=1,SL=0,R=0即可。此时CPU就会用输出指令,往8259A发出一般中断结束命令,8259A收到命令后就会把当前中断服务寄存器中最高的非零IS位置0。因为在全嵌套方式中,最高的非零IS位对应了最后一次被响应和被处理的中断,也就是当前正在处理的中断,所以,最高的非零IS位的复位相当于结束了当前正在处理的中断
场景:非全嵌套方式
非全嵌套方式下,中断服务寄存器ISR无法确定当前正在处理哪级中断。此时,就要发一条特殊的中断结束命令,这个命令指出了要将中断服务寄存器中的哪位置0
设置方法:也是通过OCW2操作命令字来发送
通过初始化命令字ICW4设置
8259A通过总线驱动器连接数据总线
8259A直接与数据总线相连
通过初始化命令字ICW1设置
8259A将中断请求输入端出现上升沿作为中断请求信号
8259A将中断请求输入端出现的高电平作为中断请求信号
8259A不使用INT信号端向CPU法中断请求信号,CPU要使用软件查询来确认中断源,从而对设备进行中断服务。查询,是通过往8259A偶地址口发送操作命令字OCW3来实现的,接着,还要用输入指令从偶地址口读取8259A的查询字