汇编语言中断的开发与应用

中断的开发与应用包括 3 个方面。

(1)开发用户自己的中断。

(2)修改或替换系统的功能。

(3)在应用程序中调用系统中断。

一、开发用户自己的中断

  1. 中断服务程序的编程方法

    中断服务程序从形式上看是一个 FAR 属性的子程序,但由于使用时并非用 CALL 语句调用,而是用中断指令“INT N调用”(软中断的情况)或硬件中断申请信号激活(外部设备中断的情况),因此,它又有别于子程序。编写中断服务程序时,要遵循如下原则。

    (1)中断服务程序必须定义成 FAR 属性的过程。

    (2)中断服务程序的最后一条指令是 IRET,而不是 RET。如果是外部中断服务程序,在 IRET 指令前,应向中断控制器 8259A 发出结束中断命令 EOI,命令字为 20H。不然的话,以后 8259A 将屏蔽对同级和较低级中断的处理。

    (3)保护现场和恢复现场工作应在中断服务程序中完成。

    (4)若中断是允许嵌套的,在中断服务程序入口处要立即开中断,以允许较高级的中断嵌套。

    (5)在中断服务程序中,不能使用“INT 21H”的系统功能调用。

    (6)中断服务程序要尽量简洁,避免占用较长的 CPU 时间,干扰其他同级和低级中断的实时处理。

    下面给出一个中断服务程序的框架结构:

    中断服务程序的框架结构

  2. 软中断初始化程序设计方法

    开发用户自己的中断,除了掌握中断服务程序的编程方法外,还要掌握中断初始化程序设计方法。由于外部中断的初始化涉及中断控制器 8259A 的初始化编程,因此,这里仅介绍软件中断的初始化程序设计方法。

    初始化工作一般要完成两个任务:一是将中断服务程序的入口地址写入中断向量表;二是根据需要将中断服务程序驻留在内存中。将中断服务程序常驻内存,它就会如同操作系统的一部分一样,供多个应用程序使用。否则,它会随主程序执行结束而消失。

    下面举例说明其方法。

    【例 1】 编程完成如下任务:开发一个名为 MYINT 的中断服务程序(具体功能略去),使其能作为 60H 号中断被任何程序所调用。

    实现上述功能的程序如下:

    中断服务程序的框架结构

    从标号 INIT 开始为初始化程序,首先使用 25H 系统功能调用将中断服务程序入口地址置入向量表中 60H 向量处。接着使用 31H 功能使中断服务程序驻留并退出初始化程序。31H 功能入口要求在 DX 中给出驻留空间的节长度,一节等于 16 字节。

    向中断向量表写中断向量也可以直接用指令写入而不使用 25H 功能。另外,程序驻留长度也可以简单地估计而省去精确计算过程。这样初始化程序可用下面的方法完成:

    中断服务程序的框架结构

    思考:为什么在修改中断向量表时要关中断?

二、修改或替换系统中断

通过上面介绍的设置中断向量的方法,用自行开发的中断服务程序的入口地址替换系统原有的中断向量,从而方便地替换系统原有的中断功能。

还可以实现在原系统中断服务程序上增加某些功能。其方法是:将原系统中断服务程序的向量从向量表中移到其他未被占用的中断号中(即改变原中断的类型号),而将新增加的功能例程的入口置入原中断号中,在新的例程完成新增的功能之后再调用原中断服务程序,以实现原中断功能。

【例 2】 1BH 中断是 ROM-BIOS 提供的一个系统功能,每当有 Ctrl+Break 组合键按下时自动产生该中断,其服务程序的功能是中止当前程序的执行,返回操作系统状态。现要求编程修改其功能为:当按下 Ctrl+Break 组合键产生中断后,首先在屏幕上提示用户是否真的中止当前程序,当用选择是(按下 y 键或 Y 键)时,就执行原 1BH 中断服务程序;当用户选择否(按下 n 键或 N 键)时,则不做任何处理,立即从中断返回,继续原程序执行。

程序如下:

修改或替换系统中断 修改或替换系统中断

程序的初始化部分先将原 1BH 中断的向量移到向量表 60H 中断处,此后,调用 60H 中断就相当于调用 1BH 中断,然后将新的 1BH 中断服务程序入口置入向量表 1BH 中断处,最后将新的 1BH 中断服务程序驻留。

程序中用到了系统调用的 35H、25H、31H 等系统功能调用,它们的调用参数请见附录。

【例 3】 定时任务的后台调度。

在实际应用系统中,很多任务需要定时处理,如定时采集数据、定时存盘、定时打印等。现假设有 3 个需要定时处理的任务,它们对应的 3 个处理程序为 SUB1、SUB2 和 SUB3,设 SUB1 每 10 秒钟需要执行一次,SUB2 每 10 分钟执行一次,SUB3 每小时执行一次,编程实现这 3 个任务的后台调度。

分析:所谓后台调度是指这个调度程序不能影响 CPU 执行其他程序(前台),CPU 在运行某个程序时,并不感知调度程序的存在。因此,这个调度程序必须在中断方式下被启动,而且要经常被启动,以确保被它调度的任务得到实时处理。

在 BIOS 中断中,有一个 1CH 号中断,它是在 08H 时钟中断(由定时器每 55ms 产生一次,以处理日时钟变化)的中断处理程序中执行了一条“INT 1CH”指令产生的。而它的中断处理程序仅为一条返回指令。这样系统提供了一个每 55ms 就自动产生一次的中断,它是一个用户中断,其中断处理程序要由用户根据需要自己去开发。

可以将定时任务调度程序作为 1CH 中断的处理程序,这样调度程序就每隔 55ms 被系统自动执行一次,每次进入中断后可进行加1计数,判断某个任务执行时间是否到达。

定时调度流程如图 3 所示。

定时调度流程

图 3 定时调度流程

程序清单如下:

定时任务的后台调度

作为练习,可将 3 个任务的子程序用显示 3 个不同的字串代替,来体验一下任务调度程序的执行情况。

三、在应用程序中调用系统中断

中断调用是汇编语言程序设计的一个重要手段。用户可调用的系统中断程序除了系统提供的用户中断(如“INT 21H”系统功能调用中断)外,主要是由 BIOS 提供的用于设备驱动的中断,如显示驱动程序(INT 10H)、硬盘驱动程序(INT 13H)等。系统将这些功能程序的入口都初始化在中断向量表中,使应用程序能够用 INT 指令方便地调用。

由于很多中断调用涉及其他一些原理的概念,所以这里不再举例。

请参阅

(完)

comments powered by Disqus