本期源码,欢迎star:
https://github.com/ZYKWLJ/assembly4-homework
本系列将讲解《汇编语言》一书,本节讲解**【汇编语言】12-内中断**。
| 本节速览 |
|---|
| 1.中断是指? |
| 2.中断分为那几类?他们的区别在于? |
| 3.内中断的产生种类有? |
| 4.中断类型码是指?大小多大? |
| 5.中断向量表是指?CPU是怎么找到中断向量表的? |
| 6.中断向量表的表项大小多大?怎么存数据的? |
| 7.中断向量表和中断类型码的联系是? |
| 8.一口气说出CPU中断的整个过程? |
| 9.iret指令是指?作用是? |
| 10.在除法错误中断处理程序中,如何得出整个中断代码段的长度的? |
| 11.说出整个除法错误中断处理程序的架构。 |
导读:
任何一个通用的CPU,比如8086,都具备一种能力,可以在执行完当前正在执行的指令之后,检测到从CPU外部发送过来的或内部产生的一种特殊信息,并且可以立即对所接收到的信息进行处理。这种特殊的信息,我们可以称其为:中断信息。
一、中断基础
1.中断定义
中断的意思是指,CPU不再接着(刚执行完的指令)向下执行,而是转去处理这个特殊信息。
2.中断的分类
中断信息可以来自CPU的内部和外部,这一章中,我们主要讨论来自于CPU内部的中断信息。
3.内中断的产生种类
上面说到,中断是指CPU停止执行当前的指令,转而马上去执行产生中断信息的程序。中断又分为内中断、外中断。那什么情况会让CPU产生内中断呢?
有以下4种产生内中断的方式,CPU需要停下当前的工作,立刻去执行它们:

显然,这四种中断方式肯定代表着不同的中断信息来源,那么,8086用什么来表示呢?用中断类型码来表示。
4.中断类型码
中断类型码为一个字节型的数据,可以表示256种中断信息的来源(2^8=256)。上述的4种中断源,在8086CPU中的中断类型码如下:
| 中断来源 | 中断类型码 |
|---|---|
| 除法错误 | 0 |
| 单步执行 | 1 |
| 执行into指令 | 4 |
| 执行int n指令 | 指令格式为int n,n就是CPU的中断类型码 |
5.中断处理程序
CPU识别到中断源后,需要立马转去执行的那段程序叫中断处理程序。
归根到底,中断处理程序也是一段普通的程序,可以由我们编程决定。那么显然,我们要让CPU的CS和IP寄存器分别指向中断处理程序的段地址、偏移地址,才得以执行中断程序。
同时,中断信息的唯一标识就是中断类型码,那么显然,CPU的设计者需要在中断类型码和中断程序的段地址、偏移地址(也即中断程序入口地址)之间建立某种联系,让CPU能够通过中断类型码唯一定位到指定的中断处理程序。通过什么机制实现呢?
通过中断表实现。
6.中断向量表
中断向量表是指以一系列中断处理程序的首地址组成的数组。
CPU用8位的中断类型码作为中断向量表数组的索引,找到对应的中断处理程序入口地址。
具体来说,一个入口地址诸如 0000:0200 ,占4字节,2个字。所以中断向量表的一个表项就占2个字,高字存段地址,低字存偏移地址。
例, 中断类型码位1,则对应的中断处理程序的段地址为1* 4,偏移地址为1* 4+2。

现在我们梳理一下,从最基本的中断信息,对应到唯一的中断类型码,再依据此码作为中断向量表的索引,终于找到了中断处理程序的地址。
现在唯一的问题就是,我们怎么知道中断向量表在哪里呢?
答案是中断向量表存在于硬件固定的ROM中.
7.存放中断向量表的ROM区
从 第一章的计算机基础知识 得知,所有硬件都被抽象成一个抽象的内存地址空间,CPU通过这个抽象的地址空间进行访问硬件。
其中一些内存空间,会被操作系统接管,我们平时自己的进程申请空间本质上还是向操作系统申请。
但是也有一部分内存空间,是固化在硬件中的,不被操作系统接管的,比如我们的ROM。(这里面就装有引导操作系统这个程序的BIOS程序,是写死的。)
我们的中断向量表就存在ROM中。
在8086CPU中,中断向量表存在于00000:0000-00000:03FFh空间里,一共占用1KB内存,按照一个地址4字节,可以存放256个中断处理程序的入口地址(这也和8字节中断码的256种情况匹配)。
8.验证ROM和普通内存区域(ds)与OS的关系
上点提到,RMA不被OS接管,而其余绝大多数内存都是被OS接管的。我们通过程序验证。
此篇幅较多,为了不偏离主题,另起介绍,请查阅此文: 验证ROM和普通内存区域(ds)与OS的关系。
9.中断过程
说了这么多,中断的过程很简单,就是CPU停下当前的指令执行,转而去执行触发中断源的中断处理程序,处理完后,又回到原来的地方继续执行接下来的指令。
那么CPU硬件成体系的处理过程的数学形式是什么样呢?
如下:
(1) (从中断信息中)取得中断类型码;
(2) 标志寄存器的值入栈(因为在中断过程中要改变标志寄存器的值,所以先将其保存在栈中);
(3)设置标志寄存器的第8位TF和第9位IF的值为0(这一步的目的后面将介绍);
(4)CS的内容入栈;
(5)IP的内容入栈;
(6)从内存地址为中断类型码*4和中断类型码*4+2的两个字单元中读取中断处理程序的入口地址设置IP和CS。
如果 更加简洁地描述 ,就是:

在最后一步完成后,CPU开始执行由程序员编写的中断处理程序。
10.中断的随机性和中断程序的常驻性
由于CPU随时都可能检测到中断信息,也就是说,CPU随时都可能执行中断处理程序,所以
中断处理程序必须一直存储在内存某段空间之中。
而中断处理程序的入口地址,即中断向量,必须存储在对应的中断向量表表项中。
11.中断处理程序的模版及 iret 指令的功效
中断处理程序和子程序编写过程几乎一致,以下是常规步骤:

其中,iret 指令的功能等价为下述汇编:
pop IP
pop CS
popf
iret 通常和硬件自动完成的中断过程配合使用。可以看到,在中断过程中,寄存器入栈的顺序是标志寄存器、CS、IP,而iret的出栈顺序是IP、CS、标志寄存器,刚好和其相对应,实现了用执行中断处理程序前的CPU现场恢复标志寄存器和CS、IP的工作。 iret 指令执行后,CPU回到执行中断处理程序前的执行点继续执行程序。
二、实现自己的中断处理程序
1.除法中断背景介绍
当CPU执行div等除法指令的时候,如果发生了除法溢出错误,将产生中断类型码为0的中断信息,CPU将检测到这个信息,然后引发中断过程,转去执行0号中断所对应的中断处理程序。我们看一下下面程序的执行结果,如图12.2所示(不同的操作系统下显示可能不同)。
;验证除法错误中断处理程序。
assume cs:codesg
codesg segment
start_:
mov ax,1000h
mov bh,1;因为这里是8位的,所以商放在al中,余数放在ah中,但是8位的al只能表示最多FF,商的结果却是1000h,严重超出,会产生除法错误中断
div bh
end_:
mov ax, 4c00h
int 21h
codesg ends
end start_

我们可以看到,触发除法中断后,确确实实发生了中断处理过程,并调用了 iret继续返回执行中断前的指令 ,注意,这里没有显示"Divide overflow"错误信息,是因为我们还没有安装好除法错误的中断处理程序。

最低0.47元/天 解锁文章
1628

被折叠的 条评论
为什么被折叠?



