汇编语言 第十二章 内中断

中断信息,可以理解为更紧急、需要优先处理的信息,在执行指令过程中接收到中断信息,CPU会优先处理,而不是继续向下执行。

例如你正在刷抖音,厨房着火了你应该先去灭火而不是继续刷下一条抖音。

那么对于CPU而言,什么是需要优先处理的中断信息呢?有以下四种

  • 除法错误。除数为0或者除法溢出
  • 单步执行。debug中的T命令就是单步执行中断信息
  • 执行into指令
  • 执行int指令

那么CPU如何识别不同的中断信息?

使用的是中断类型码,(相当于用中断类型码给各类中断信息编号)中断类型码是一个字节型数据,可以表示256种中断信息的来源。(实际中断类型远少于256)

  • 除法错误:0
  • 单步执行:1
  • 执行into指令:4
  • 执行int指令:int n 其中n为字节型立即数,作为cpu的中断类型码

正在刷抖音(正常执行指令),你(CPU)根据冒出来的烟(中断类型码),发现这是着火了(对应某种中断信息),你知道要去救火了,那CPU接下来要干什么呢?

CPU当然是去执行相关的中断处理程序,CPU根据CS:IP执行指令,那么中断处理程序的入口地址在哪里呢?又要如何把它的赋给CS和IP呢?

CPU中的中断处理程序地址都存储在中断向量表。中断向量表在8086CPU中,CPU中存储在0000:0000~0000:03FF这1024个字节中(256个表项,和中断类型码一一对应

四个字节为一个表项,前两个字节存储中断处理程序的偏移地址,后两个字节存储其段地址。表项和中断类型码是一一对应的。例如除法指令类型码为0,它的中断处理程序的地址就存在第0个表项中,也就是0-3字节。中断类型码为N,对应中断处理程序偏移地址储存在4*N,段地址储存在4*N+2

 中断过程:

  1. 从中断信息中取得中断类型码N
  2. 将标志寄存器的值入栈(因为中断过程中标志寄存器的值会被改变,将其入栈保存)pushf
  3. 将TF和IF均置0 ;TF = 0,IF = 0   CPU在执行完一条指令后,如果检测到TF = 1,那么就产生单步中断,执行相应的中断处理程序,而中断处理程序也是一条条指令组成的。执行中断处理程序之前TF = 1,执行完中断处理程序第一条之后,如果TF仍为1,这时就又要跳转,从头再执行中断处理程序,如此形成死循环。为避免这种执行中断处理程序的发生单步中断,CPU会再中断处理程序执行之前将TF置零。
  4. CS中的内容入栈    push CS
  5. IP中的内容入栈    push IP
  6. 从中断向量表中读取内存单元,(4*N)赋给IP,(4*N+2)赋给CS    (IP) = (4*N)    (CS) = (4*N+2)

到这时CS和IP都被设置好了,CPU开始执行中断处理程序。

中断处理程序:

类似于子程序,以下是常规的步骤:

  1. 保存用到的寄存器,入栈保存
  2. 处理中断
  3. 恢复用到的寄存器,出栈恢复
  4. 用IRET指令返回

iret指令:

 出栈顺序与中断过程中的入栈相反,保证了初始值都不变。

pop IP

pop CS

popf

小小tips:

  1. 编译器可以识别并直接运算加减乘除(+、-、*、/)
  2. 如何知道一段代码的字节长度?可以用标号偏移地址相减表示。例如要知道循环s的长度,可以在loop s之后在写一行 send:nop    offset send - offset s就是s段的长度了,不同的标号之间也可以这样处理。

响应中断的特殊情况

执行完设置ss寄存器的指令后,不响应中断。中断信息的优先级比一般指令要高,相对一般指令优先执行;但设置ss的值优先级要比中断信息更高,执行完设置ss的指令及其下一条指令之后,才可能响应中断信息。所以应将设置ss和sp的指令连续存放。

posted @ 2021-10-27 23:26  海萌萌萌萌萌萌  阅读(92)  评论(0编辑  收藏  举报