第十二章 内中断


中断的作用就是暂停当前程序的执行,并转去执行另外一个程序,另外个程序执行完后再回来继续执行当前程序。该过程和callreturn有点像,不过中断是由硬件主动产生的。

系统内置的内中断

  1. 除法错误,比如执行div指令产生的除法溢出 >>> 0
  2. 单步执行 >>> 1
  3. 执行into指令 >>> 4
  4. 执行int指令 >>> N

CPU是根据 >>> 后面的中断类型来判断,触发内中断的原因是什么。这里特别要注意一下 int指令,该指令的使用形式是 int N,N是自定义的一个类型。

中断处理程序

CPU在收到中断信息后,需要跳转到指定程序处理中断,那么如何处理中断,就应该有我们来编写。这类用于处理某一种中断信息的程序叫做 中断处理程序。比如现在触发了 中断类型码为4的中断,CPU收到该中断后,会去 中断向量表 内查找该中断的处理程序,找到后跳转到 中断处理程序的起始位置并执行。

中断向量表

CPU用8位的中断类型码通过中断向量表来查找相应的中断处理程序所在的位置。

中断向量表内存放了256个中断源对应的中断处理程序的起始地址,如果把一个中断处理程序的地址作为一个项,总共有256个项,每个项包含两个字节(一个字),字的高位放段,字的低位放偏移量。

中断向量表放在 0000:00000000:03FF的1024个单元中。

中断向量表

中断过程

  1. CPU收到中断类型码N
  2. 保存标志寄存器
  3. 将TF和IF设置为0(防止后面单步执行的中断使其陷入死循环)
  4. 保存CS和IP
  5. 从 0:(N * 4)读出段地址,再从 0:(N * 4 + 2)独处偏移地址,然后调用对应的中断处理程序。

中断处理程序和iret指令

前面可以得知,当CPU收到中断类型码时,会根据终端类型码获取中断处理程序的起始地址并执行;那么进入了中断处理程序该如何跳出中断呢?这里并不是简单的return即可,这里需要使用iret

iret这个指令除了继承returnpop IPpop CS的功能外,还多执行了一步popf。可以和中断过程对应一下~

中断处理程序的安装

  1. 由于中断随时可能发生,所以中断处理程序、以及它的依赖(最常见的就是一段字符串,被覆盖了)需要在内存中常驻。
  2. 将中断处理程序的入口地址设置给中断向量表

一段程序的长度测量

这里采用 offset 起始标号- offset 终点标号 就能获取一段程序的长度,比如

program_start:
    mov ax, 1
    mov bx, 1001
    ...
    mov ax, 4c00h
    int 21h

end_program:
    nop

上述程序的长度可以通过 offset program_start - offset end_program 来获得。注意,end_program一定要放在最后一个有效命令之后(比如这里多加了个nop),因为offset表示标号的第一个指令的起始偏移地址

单步中断

当TF为1时,执行一个命令,就会产生一个单步中断,单步中断的类型码为1

  1. 设置TF为1
  2. 执行一个命令
  3. 保存寄存器,保存状态,设置TF、IF为0等等
  4. 执行中断程序
  5. 恢复寄存器
  6. 继续执行命令——跳到步骤2

(上述的步骤其实就是debug程序的过程:输入一个t,将TF设置为1,然后执行命令,然后跳转到中断程序输出寄存器,最后回到debug程序中,等待下一个指令)首先设置TF为1,然后每执行一次指令,都执行一下 单步中断的中断程序

这里解释了为何中断过程要特别设置TF、IF为0,因为如果步设置为0,流程就会如下所示:

  1. 设置TF为1
  2. 执行一个命令
  3. 保存寄存器,保存状态(假设不设置TF、IF为0)
  4. 执行中断程序
    • a. 执行中断程序的第一条命令
    • b. 保存寄存器,保存状态(假设不设置TF、IF为0)
    • c. 执行中断程序
    • d. 跳到步骤4.a继续执行

所以如果不设置TF、IF为0,整个程序就会陷入死循环,无法结束。

中断的特殊情况

中断并不是在任何时刻都能中断程序的,有的指令执行完后,即便发生中断,也不会去执行中断程序。最典型的就是mov ss,XX,众所周知mov ss,XX指令后面尽量要跟上mov sp,XX,而且在debug里面mov ss,XX执行完后直接跳到mov sp, XX的后面一个指令,仿佛看不到设置sp寄存器。
有的同学可能想,反正中断也会保存CSIP等数据到栈中,最后还会弹出,这应该构不成影响吧?而且最后回到源程序还是能正常的设置SP。

这种想法抱有了一点侥幸心里,假设此时的SS、SP(原始的,还未设置的)里面的数据不重要,被覆盖掉了还好说;如果里面的数据很重要呢?

这一小节就是解释这样一种特殊的情况————并不是所有的中断都能顺利中断程序的。

课后检测点

第十二章检测点

posted @ 2019-06-02 18:19  CoDeleven  阅读(764)  评论(0编辑  收藏  举报