汇编语言笔记:内中断
章节目录
- 概念
- 中断过程
- 示例: 0 号中断处理
作者能力有限, 如果您在阅读过程中发现任何错误, 还请您务必联系本人,指出错误, 避免后来读者再学习错误的知识.谢谢!
概念
中断信息:
任何一个通用 CPU 都具备一种能力, 可以在执行完当前正在执行的指令之后, 检测到从 CPU 外部发送过来的或者内部产生的一种特殊信息, 并且可以立即对所接受到的信息进行处理. 这种特殊的信息称为:中断信息. 中断意味着 CPU 不再继续向下执行, 而是转去处理这个特殊的信息.
CPU 内部产生的中断称为内中断
对于 8086 CPU, 有以下四种中断信息.
中断原因 | 中断类型码 |
---|---|
除法错误 | 0 |
单步执行 | 1 |
执行 into 指令 | 4 |
执行 int 指令 | n |
中断类型码是中断来源信息的编码. 在 8086CPU 中使用一个字节的长度来编码中断源.
中断处理程序:
CPU 在收到中断信息之后, 需要对中断进行处理. 中断处理程序就是用来处理对应中断的程序. CPU 在收到中断信息之后, 就会转去执行对应的中断处理程序. 中断处理程序由程序员编写.
中断向量表: 是中断向量的列表.
中断向量: 是中断程序的入口地址.
中断向量表在内存中保存, 存放着 256 个中断源所对应的中断处理程序的入口地址. CPU 根据中断类型码作为中断向量表的表项号, 定位相应的表项, 从而得到中断处理程序的入口地址.
对于 8086PC 机, 中断向量表存放在 0000:0000 ~ 0000:03FF 所在的内存中. 每个表项占用两个字节的大小. 高地址字存放段地址, 低地址字存放偏移地址.
中断过程
- 从中断信息中获取中断类型码
- 标志寄存器的值入栈
- 设置标志寄存器的第八位 TF 和第九位 IF 的值为 0.
- CS 的内容入栈
- IP 的内容入栈
- 从内存地址为中断类型码*4和中断类型码*4+2的两个单元中读取中断处理程序的入口地址放入IP和CS中
这个过程由 CPU 完成.
示例: 0 号中断处理
下面的示例中, 我们将完成一个处理除法溢出的中断处理程序. 完成后, 先执行中断处理程序, 然后当系统发生除法中断, 我们的中断处理程序就会被执行, 在屏幕中央显示 “overflow!” 字符串.
中断处理程序:
程序一开始, 我们将我们的中断处理程序 do0 和 do0Start 存储在内存位置 0:200H 开始的地址中. 没有直接申请对应的内存, 是因为不想涉及操作系统相关的操作. 0000:0000 ~ 0000:03FF 这段地址本是用来存放中断向量表的, 但是大部分情况下并没有那么多的中断处理程序, 因此我们就借用了这段地址来存储我们的中断处理程序. 将 do0 存到 0:200H 的地址中这个操作 我们使用了 movsb 指令.
中断处理程序 do0Start 完成在屏幕上显示 “overflow!” 的功能. 这里, 我们将 “overflow!” 字符串保存在代码段中, 是为了一起复制到 0:200H 中去. 如果我们为该字符串单独定义一个数据段, 那么为了能访问该数据段, 我们还需要额外的将该数据段也复制到 0:200H 相应的内存中去. 为了避免麻烦, 我们这里直接将它写在代码段中, 这样数据会和代码一次性被拷贝到相应内存中去.
因为我们处理的的是0号中断, 因此我们在设置中断向量表时, 是将对应的中断处理程序地址(0:200h) 分别设置到 0:2 和 0:0 中去.
如果单纯的编译运行该程序, 不会有任何输出, 因为该程序只是完成将0号中断处理程序保存在内存地址 0:200H 开始的内存地址中, 并将该程序的内存地址保存到 0 号对应的向量表中, 以便当发生除法中断时, 该程序会被调用.
测试代码:
使用如下代码测试一下我们的程序是否成功运行.
在我的机器上运行效果如下:
欢迎交流任何想法.
End…