汇编语言编程处理0号中断

511遇见

当CPU执行div 6h后,发生了除法溢出错误,产生。号中断信息,引发中断过程,CPU执行我们编写的0号「},断处理程序。在l1幕中间显示提示信息“overflow !”后,返回到操作系统中。

  编程:当发生除法溢出时,在屏幕中间显示 "overflow!",返回 DOS。

  分析:

  (1)当发生溢出的时候,产生 0 号中断信息,从而引发中断过程。

  此时,CPU 将进行以下工作。

  ① 取得中断类型码

  ② 标志寄存器入栈,TF、IF 设置为 0

  ③ CS、IP 入栈

  ④ (IP)=(0*4),(CS)=(0*4+2)

  (2)可见,当中断 0 发生时,CPU 将转去执行中断处理程序。

  只要按如下步骤编写中断处理程序,当中断 0 发生时,即可显示 "overflow!"。

  ① 相关处理

  ② 向显示缓冲区送字符串 "overflow!"

  ③ 返回 DOS

  我们将这段程序称为:do0。

  (3)现在的问题是:do0 应放在内存中。因为除法溢出随时可能发生,CPU 随时都可能将 CS:IP 指向 do0 的入口,执行程序。

那么do0 .该放在哪LI毛昵?
山于我们是在操作系统之上使用计算机,所有的硬件资源都在操作系统的管理之下,所以我们要想得到块内存区存放doO,应该向操作系统申请。但在这里出于两个原因我们不想这样做:

①过多地讨论申请内存将偏离问题的主线;
②我们学习汇编的一个重要目的就是要获得对计算机底层的编程体验。所以,在可能的情况下,我们不去理会操作系统,而直接面向硬件资源。
问题变得简单而直接,我们只需找到一块别的程序不会用到的内存区,将do0传送到其中即可。
前面讲到,内存0000:0000-0000:03FF,大小为1KB的空间是系统存放中断处理程序入口地址的中断向量表。8086支持256个中断,但是,实际上,系统中要处理的中断事件远没有达到256个。所以在中断向量表中,有许多单元是空的。
中断向量表是PC系统中最重要的内存区,只用来存放中断处理程序的入口地址,DOS系统和其他应用程序都不会随便使用这段空间。可以利用中断向量表中的空闲单元来存放我们的程序。一般情况下,从0000:0200至0000:02FF的256个字节的空间所对应的中断向量表项都是空的,操作系统和其他应用程序都不占用。我们在前面的课程中使用过这段空间(参见5.7节)。根据以前的编程经验,我们可以估计出,do0的长度不可能超过256个字节。

  我们把程序 do0 传送到内存 0000:0200 处。

  (4)将中断处理程序 do0 放到 0000:0200 后,若要使得除法溢出发生的时候,CPU 转去执行 do0,则必须将 do0 的入口地址,即 0000:0200 登记在中断向量表的对应表项中,因为除法溢出的中断类型码为 0,它的中断处理程序的入口地址应该从 0*4 地址单元开始存放,段地址存放在 0*4+2 字单元中,偏移地址存放在 0*4 字单元中。也就是说要将 do0 的段地址 0 放在 0000:0002 字单元中,将偏移地址 200H 存放在 0000:0000 字单元中。

  总结上面的分析,我们要做以下几件事情。

  (1)编写可以显示“overflow!”的中断处理程序:do0

  (2)将 do0 送入内存0000:0200 处

  (3)将 do0 的入口地址 0000:0200 存储在中断向量表 0 号表项中。
程序的框架如下

assume cs:code 
code segment
 
start:    do0 安装程序
          设置中断向量表
    mov ax,4c00h
    int 21h
 
do0: 显示字符串"overflow!"
    mov ax,4c00h
    int 21h
 
code ends
 
end start


  可以看到,上面的程序可分为两部分:

  (1)安装 do0,设置中断向量的程序
  (2)do0
  程序12.1执行时,do0的代码是不执行的,它只是作为do0安装程序所要传送的数据。程序12.1执行时,首先执行do0安装程序,将do0的代码复制到内存0:200处,然后设置中断向量表,将do0的入口地址,即偏移地址200H和段地址0,保存在0号表项中。这两部分工作完成后,程序就返回了。程序的目的就是在内存0:200处安装do0的代码,将0号中断处理程序的入口地址设置为0:200 o do0的代码虽然在程序中,却不在程序执行的时候执行。它是在除法溢出发生的时候才得以执行的中断处理程序。
do0部分代码的最后两条指令是依照我们的编程要求,用来返回DOS的。
现在,我们在反过来从CPU的角度看一下,什么是中断处理程序?我们来看一下do0是如何变成0号中断的中断处理程序的。
(1)程序12.1在执行时,被加载到内存中,此时do0的代码在程序12.1所在的内存空间中,它只是存放在程序12.1的代码段中的一段要被传送到其他单元中的数据,我们不能说它是0号中断的中断处理程序;
(2)程序12.1中安装do0的代码执行完后,do0的代码被从程序12.1的代码段中复制到0:200处。此时,我们也不能说它是0号中断的中断处理程序,它只不过是存放在0:200处的一些数据;
(3)程序12.1中设置中断向量表的代码执行完后,在0号表项中填入了do0的入口地址0:200,此时0:200处的信息,即do0的代码,就变成了0号中断的中断处理程序。因为当除法溢出(即0号中断)发生时,CPU将执行0:200处的代码。

  回忆一下:

  我们如何让一个内存单元称为栈顶?将它的地址放入 SS、SP 中;
  我们如何让一个内存单元中的信息被 CPU 当作指令来执行?将它的地址放入 CS、IP 中;
  那么,我们如何让一段程序称为 N 号中断的中断处理程序?将它的入口地址放入中断向量表的 N 号表项中。


发布日期:

所属分类: 编程 标签:  


没有相关文章!