❤️💕💕汇编语言目前仍在发挥着不可替代的作用,在效率上无可替代,在底层,学习linux内核,计算机外围设备和驱动,都离不开汇编。Myblog:http://nsddd.top
[TOC]
一个字节即一共 256 个中断,0000H~FFFFH
。
定义:内部硬件中断是由某些特殊的指令触发的,例如单步中断、除法出错中断。通常我们所说的硬件中断即指内部硬件中断。
硬件中断举例:在使用 DEBUG 调试程序时我们经常使用 T 命令和 P 命令,而 T 命令和 P 命令的执行恰好正是利用了内部硬件中断。
(1)INT 00H:除法错误中断。
(2)INT 01H:单步中断,由 T 命令产生。
- 它的特征是将陷阱标志位 TF 置位,这样当程序运行时,会在每一条指令的后面产生一个单步中断,从而中止指令的继续执行。
(3)INT 03H:断点中断,由 P 命令产生。
- 与 INT 01H 类似,但不会跟踪进子程序、中断调用等。
(4)INT 04H:溢出中断。
- 在指令序列中,若上一个指令由于某些特殊原因使溢出标志 OF 置 1,那么当执行溢出中断指令 INTO 是立即产生中断 04H;若 OF 为 0,则 INTO 不起作用。
定义:外部硬件中断是指从处理器外部的硬件设备中产生并发向处理器的中断。
分类:分为可屏蔽中断和不可屏蔽中断两种。分别由 **INTR 引脚
**和 **NMI 引脚
**的信号来触发。即有 2 条外部中断请求线。
-
可屏蔽中断–INTR
- 可以通过设置中断控制器的屏蔽参数来禁止某些指定的中断。
- 可屏蔽中断还可以通过指令 CLI(关中断)来禁止 CPU 响应所有的外部中断。
-
不可屏蔽中断–NMI
是用来处理一些紧急情况的,如机器掉电等。它不能由用户通过编制软件来屏蔽,一旦 CPU 接收到 NMI 引脚上的信号时就必须立即响应,转向 NMI 的服务程序,硬件将自动完成断点保护及现场保护,且在中断返回时执行一条 RETN 指令。
定义:严格说来,软件中断是内部中断的一种,是由软件引起的非屏蔽型中断。
CPU 执行 INT n 指令时,立即产生一个软件中断,中断的类型由指令中的 n 指明。 **应用:**因为指令中可以指定任何的类型号,故此指令可以方便地用来调试为外设编好的中断服务程序。
中断过程中很关键的一步是要由中断处理程序对因各种原因触发的相应中断进行处理。因此每一个中断都要对应的有一个中断处理程序。对这些中断进行管理的就是中断向量表了。
(1)中断向量表结构
- 中断向量表的长度为 1K 字节(1024 字节),共有 256 项,每一项 4 个字节,对应一个中断。也就是说一张表中断最多可对应 256 个中断(当然,实际上并没有这么多中断,这就为用户自己编制并扩充中断服务程序提供了便利的条件)
- 中断向量表在内存中靠前的部分并固定在这个段地址为 00H,偏移量为 00H~3FFH,即 00000H—003FFH 的位置。
- 中断向量表每项的四个字节存放着该项对应中断的中断处理程序的入口地址。四个字节也就是两个字,高字存放中断处理程序入口地址的段 CS,低字存放偏移 IP。
(2)中断服务程序的调用
- 中断指令 INT n 发出以后,就要到向量表中去找其对应的服务程序的地址。
- n * 4 所得到的就是中断 INT n 所对应的 n 号中断的四个字节地址在向量表中的首地址。
- 由首地址开始的四个连续字节即两个字中顺序存放着其对应中断服务程序的入口地址的偏移和段地址,然后程序跳到此入口地址,并将控制交给中断服务程序。
(3)中断向量表的优点
- 便于管理和扩充,就像通过仓库存货单可以找到任何一件存储的物品那样,我们可以通过向量表来找到每一个中断对应的中断服务程序。
- 当用户想要编制和使用自己的中断服务程序时,可以先设置中断向量,以确定该中断在中断向量表中的位置,然后将自己编制的中断服务程序(可以是驻留内存的,也可以是非驻留内存的)的地址返回给它在中断向量表中对应位置的两个字中,至此,用户就可以十分方便地为自己建立一个软中断了。
例一:保存 5 号中断入口,然后重置 5 号中断的入口
PUSH ES
MOV AX,3505H ;取中断向量
INT 21H
MOV [OLD_IP],BX ;保存旧的偏移地址
MOV [OLD_ES],ES ;保存旧的段地址
POP ES
MOV AX,2505H ;重置中断向量
MOV DX,OFFSET INT05H
INT 21H
(1)INT 00H ~ 05H 自动提供
- INT 00H — 除法错误
- INT 01H — 单步错误
- INT 02H — 非屏蔽中断 NMI
- INT 03H — 断点中断
- INT 04H — 溢出中断
- INT 05H — 屏幕打印(拷屏)中断
软中断被响应后,CPU 进入中断响应周期。CPU 将中断类型号乘以 4,得到中断向量表的入口地址,并执行一下动作:
(1)将标志寄存器压入堆栈。
(2)用清中断标志(IF)和单步标志(TF)禁止硬件中断,即关中断。
- 所以当我们自己编制中断服务程序时,在程序内必要时可以开中断,即打开由硬件自动关闭的中断允许触发器,使之能够响应更高级的中断。
(3)将当前代码段寄存器的内容(CS)压栈。
(4)将当前指令指针(IP)压栈。
- 步骤(3)、(4)的目的是要确保中断处理完毕之后能够正确地返回中断调用者。
(5)转向中断服务程序入口并将控制交给中断服务程序。
在中断服务程序执行完后,即 CPU 接收到 IRET 指令时,它又将产生以下步骤:
- (1)弹出 IP:从堆栈中将保存的指令指针 IP 由堆栈弹出到 IP 中。
- (2)弹出 CS:将保存的段寄存器内容由堆栈弹出到代码段寄存器中。
- (3)恢复标志寄存器
中断服务程序可以按各个设备的要求来加以编制,但一般有:
(1)保护现场(入栈)
(2)恢复现场(出栈)
(3)中断返回(IRET)
**说明:**软中断指令非常类似子程序调用的 CALL 指令(即中断的 INT 21H 指令),但两者之间还是有明显区别的:
(1)软中断全部都是段间的调用,所以在结束时用 IRET 返回;
(2)软中断的 IRET 指令具有自动恢复断点和标志的功能。
一般情况下,目前使用的软中断可分为三大类:
-
(1)BIOS 中断 — 10H ~ 1FH(16 个)
- 它主要是提供 I/O 驱动程序使用,提供了应用程序、DOS 与设备的接口功能。用户可以忽略对具体设备硬件上的了解,直接应用这些功能调用完成对具体设备的控制。
-
(2)DOS 中断 — 20H ~ 3FH(32 个)
- 目前使用了其中的 20H ~ 27H 和 2FH,其余的为保留中断。
-
(3)自由中断 — 40H ~ FFH(192 个)
- 这类中断是由系统或应用程序设置开发的。可以理解为这类中断是系统或应用程序为了完成特定的功能而扩展出来的中断。可以看得出来,系统给自身和应用程序留下了相当大的余地。这类中断是不定。
软中断的访问在不同的环境中有不同的形式,在这里我们仅仅就汇编语言对软中断的访问讨论一下。用汇编语言申请一个标准 DOS 或 BIOS 中断是非常简单的,用户程序通过规定的寄存器与中断服务程序之间进行内定的规范的信息交换。大部分的中断处理程序都有一个入口和一个出口,在入口处用寄存器传入规定的数据,在中断请求完毕之后再通过特定的寄存器传递出返回值。
MOV DL,'A'
MOV AH,02H
INT 21H ;显示一个字符