目录
概述
CPU正常的运行是,不停的取指令,解码,执行,写回。正常与CPU交流的方式就是指令。因为CPU是计算机中的核心处理器,所以计算机中发生的所以事件都必须通过CPU。一般的事件都是同时发生,除了正常的执行流程外,意外和问题也会不时的发生。如主板上的电路可能出错,执行可能遇到非法指令。各种不同的状况不停发生,会中断CPU当前流程。虽然情况复杂,但是CPU必须负责到底。所以CPU必须有一个机制,在收到这些信号后,能及时对这些中断进行处理。
捕获中断
首先对这些事件分类,可能发生在外部,为外部硬件中断,也可能发生在内部,为内部软件中断。发生在内部,直接内部接收处理。发生在外部,得提供外部设备跟CPU通信的窗口。对于8086来说,在CPU中提供了两个引脚来让外部设备告诉CPU发生了一些什么事情。
中断编号
CPU为了防止事件的蜂拥而至,给各事件都编了号码。这就是中断编号,CPU只要看到事件的编号,就知道发生啥事了。
CPU设置了256个编号:0x00---0xff。
其中:0x00--0x07 为错误/异常编号:
INT 00h | CPU:除零错,或商不合法时触发 |
INT 01h | CPU:单步陷阱,TF标记为打开状态时,每条指令执行后触发 |
INT 02h | CPU:非可屏蔽中断,如引导自我测试时发生内存错误 |
INT 03h | CPU:第一个未定义的中断向量,约定俗成仅用于调试程序 |
INT 04h | CPU:算数溢出。通常由INTO指令在置溢出位时触发 |
INT 05h | 在按下Shift-Print Screen或BOUND指令检测到范围异常时触发 |
INT 06h | CPU:非法指令 |
INT 07h | CPU:没有数学协处理器时尝试执行浮点指令触发。 |
0x08--0x0f:默认情况下是处理外部设备产生的中断。
INT 08h | IRQ0:可编程中断控制器每 55 毫秒触发一次,即每秒 18.2 次 |
INT 09h | IRQ1:每次键盘按下、按住、释放 |
INT 0Ah | IRQ2: |
INT 0Bh | IRQ3:COM2/COM4 |
INT 0Ch | IRQ4:COM1/COM3 |
INT 0Dh | IRQ5:硬盘控制器(PC/XT下)或 LPT2 |
INT 0Eh | IRQ6:需要时由软盘控制器调用。 |
INT 0Fh | IRQ7:LPT1 |
注:IRQ2是一个扩展,用于链接从片,前面说外部设备与CPU连接的引脚INTR,通常会使用8259A芯片,是一个可编程中断控制器。可拓展8个引脚,对应上图8位,下图可示:
而外部中断想要进入CPU中处理,需要经过两个步骤:
首先是通过8259A芯片中的IMR,设置不屏蔽,捕获。
其次是在CPU中的EFLAGS寄存器IF位,设置是否为相应可屏蔽硬件中断。
所以从INTR引脚接入的外部中断是可屏蔽的。
而由NMI接入的外部中断不可屏蔽,不受以上两种的影响。且只有非常严重的事件才通过它传达。比如:读取内存电路校验错误,或者UPS电源发来的停电通知。占用(0x02中断号)
0x10--0x1A: BIOS中断 用于提供显示,硬盘,键盘等输入输出。
其他:用户可自己定义中断。如linux的0x80中断,微软DOS系统提供的DOS中断。
优先级:在硬件层面进行了划分,首先NMI的优先级要高于INTR,NMI要先处理,IRQ的编号越小,优先级越高。
处理程序
执行程序-->程序内存地址:
段地址:偏移地址 组成
2字节: 2字节
一共有256个中断号,会占据256*4字节共1KB的空间。
寻址逻辑:
0x00号中断地址占据0x0000:0000~0003这4个字节。
0x01号中断地址占据0x0000:0004~0007这4个字节。
依次内推。
每一项都是相同格式的内存地址,他存储了中断号对应的处理程序地址,这些地址指向了处理程序的入口点。这张表就叫中断向量表,简称IVT。
中断号生成:
①自动生成
它碰到了除数0,则生成0x00号中断
执行中遇到非法指令则生成0x06号中断
②指令生成
INT3 INTO BOUND INT
这些都是在软件执行中产生的。
③硬件中断
INTR(8259A)/NMI
执行处理程序
首先要保护现场,不能影响原来程序的执行,所以中断处理前要保存寄存器的值,在执行中尽情使用,执行后还要恢复这些寄存器的值。
保存寄存器的值,可以通过push/pop来进行。
还可以在使用INT指令调用前,使用ah寄存器指定参数来传递参数。
磁盘服务,它不光需要传递参数,指定功能,而且像读扇区这种功能还有返回值,必须指定读取的数据放哪。
如果是自己定义的中断处理函数,在程序最后一定要加iret指令(中断返回),跳回到原来的程序继续执行。