汇编语言笔记(四):内中断

Posted by Useless Programmer on July 21, 2018

    汇编语言笔记:内中断

章节目录

  1. 概念
  2. 中断过程
  3. 示例: 0 号中断处理

作者能力有限, 如果您在阅读过程中发现任何错误, 还请您务必联系本人,指出错误, 避免后来读者再学习错误的知识.谢谢!

概念##

中断信息:
任何一个通用 CPU 都具备一种能力, 可以在执行完当前正在执行的指令之后, 检测到从 CPU 外部发送过来的或者内部产生的一种特殊信息, 并且可以立即对所接受到的信息进行处理. 这种特殊的信息称为:中断信息. 中断意味着 CPU 不再继续向下执行, 而是转去处理这个特殊的信息.

CPU 内部产生的中断称为内中断

对于 8086 CPU, 有以下四种中断信息.

中断原因 中断类型码
除法错误 0
单步执行 1
执行 into 指令 4
执行 int 指令 n

中断类型码是中断来源信息的编码. 在 8086CPU 中使用一个字节的长度来编码中断源.

中断处理程序:
CPU 在收到中断信息之后, 需要对中断进行处理. 中断处理程序就是用来处理对应中断的程序. CPU 在收到中断信息之后, 就会转去执行对应的中断处理程序. 中断处理程序由程序员编写.

中断向量表: 是中断向量的列表.
中断向量: 是中断程序的入口地址.

中断向量表在内存中保存, 存放着 256 个中断源所对应的中断处理程序的入口地址. CPU 根据中断类型码作为中断向量表的表项号, 定位相应的表项, 从而得到中断处理程序的入口地址.

对于 8086PC 机, 中断向量表存放在 0000:0000 ~ 0000:03FF 所在的内存中. 每个表项占用两个字节的大小. 高地址字存放段地址, 低地址字存放偏移地址.

中断过程##

  1. 从中断信息中获取中断类型码
  2. 标志寄存器的值入栈
  3. 设置标志寄存器的第八位 TF 和第九位 IF 的值为 0.
  4. CS 的内容入栈
  5. IP 的内容入栈
  6. 从内存地址为中断类型码*4和中断类型码*4+2的两个单元中读取中断处理程序的入口地址放入IP和CS中

这个过程由 CPU 完成.

示例: 0 号中断处理##

下面的示例中, 我们将完成一个处理除法溢出的中断处理程序. 完成后, 先执行中断处理程序, 然后当系统发生除法中断, 我们的中断处理程序就会被执行, 在屏幕中央显示 “overflow!” 字符串.

中断处理程序:

images

程序一开始, 我们将我们的中断处理程序 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 号对应的向量表中, 以便当发生除法中断时, 该程序会被调用.

测试代码:

使用如下代码测试一下我们的程序是否成功运行.

images

在我的机器上运行效果如下:

images

欢迎交流任何想法.

End…