【汇编语言】12-内中断+中断程序实战


公粽号「专注Linux」,专注Linux内核开发

本期源码,欢迎star:
https://github.com/ZYKWLJ/assembly4-homework

本系列将讲解《汇编语言》一书,本节讲解**【汇编语言】12-内中断**。


本节速览
1.中断是指?
2.中断分为那几类?他们的区别在于?
3.内中断的产生种类有?
4.中断类型码是指?大小多大?
5.中断向量表是指?CPU是怎么找到中断向量表的?
6.中断向量表的表项大小多大?怎么存数据的?
7.中断向量表和中断类型码的联系是?
8.一口气说出CPU中断的整个过程?
9.iret指令是指?作用是?
10.在除法错误中断处理程序中,如何得出整个中断代码段的长度的?
11.说出整个除法错误中断处理程序的架构。

导读:

任何一个通用的CPU,比如8086,都具备一种能力,可以在执行完当前正在执行的指令之后,检测到从CPU外部发送过来的或内部产生的一种特殊信息,并且可以立即对所接收到的信息进行处理。这种特殊的信息,我们可以称其为:中断信息。

一、中断基础

1.中断定义

中断的意思是指,CPU不再接着(刚执行完的指令)向下执行,而是转去处理这个特殊信息。


2.中断的分类

中断信息可以来自CPU的内部外部,这一章中,我们主要讨论来自于CPU内部的中断信息。


3.内中断的产生种类

上面说到,中断是指CPU停止执行当前的指令,转而马上去执行产生中断信息的程序。中断又分为内中断、外中断。那什么情况会让CPU产生内中断呢?


有以下4种产生内中断的方式,CPU需要停下当前的工作,立刻去执行它们:

4种产生内中断的方式

显然,这四种中断方式肯定代表着不同的中断信息来源,那么,8086用什么来表示呢?用中断类型码来表示。

4.中断类型码

中断类型码为一个字节型的数据,可以表示256种中断信息的来源(2^8=256)。上述的4种中断源,在8086CPU中的中断类型码如下:

中断来源 中断类型码
除法错误 0
单步执行 1
执行into指令 4
执行int n指令 指令格式为int n,n就是CPU的中断类型码

5.中断处理程序

CPU识别到中断源后,需要立马转去执行的那段程序叫中断处理程序。

归根到底,中断处理程序也是一段普通的程序,可以由我们编程决定。那么显然,我们要让CPU的CS和IP寄存器分别指向中断处理程序的段地址偏移地址才得以执行中断程序。

同时,中断信息的唯一标识就是中断类型码,那么显然,CPU的设计者需要在中断类型码中断程序的段地址、偏移地址(也即中断程序入口地址)之间建立某种联系,让CPU能够通过中断类型码唯一定位到指定的中断处理程序。通过什么机制实现呢?

通过中断表实现。


6.中断向量表

中断向量表是指以一系列中断处理程序的首地址组成的数组

CPU用8位的中断类型码作为中断向量表数组的索引,找到对应的中断处理程序入口地址。

具体来说,一个入口地址诸如 0000:0200 ,占4字节,2个字。所以中断向量表的一个表项就占2个字,高字存段地址低字存偏移地址

例, 中断类型码位1,则对应的中断处理程序的段地址为1* 4,偏移地址为1* 4+2。

中断向量表是指以一系列中断处理程序的首地址组成的数组。可以记忆为  。


现在我们梳理一下,从最基本的中断信息,对应到唯一的中断类型码,再依据此码作为中断向量表的索引,终于找到了中断处理程序的地址。

现在唯一的问题就是,我们怎么知道中断向量表在哪里呢?

答案是中断向量表存在于硬件固定的ROM中.

7.存放中断向量表的ROM区

第一章的计算机基础知识 得知,所有硬件都被抽象成一个抽象的内存地址空间,CPU通过这个抽象的地址空间进行访问硬件。

其中一些内存空间,会被操作系统接管,我们平时自己的进程申请空间本质上还是向操作系统申请。

但是也有一部分内存空间,是固化在硬件中的不被操作系统接管的,比如我们的ROM。(这里面就装有引导操作系统这个程序的BIOS程序,是写死的。)

我们的中断向量表存在ROM中

在8086CPU中,中断向量表存在于00000:0000-00000:03FFh空间里,一共占用1KB内存,按照一个地址4字节,可以存放256个中断处理程序的入口地址(这也和8字节中断码的256种情况匹配)。

8.验证ROM和普通内存区域(ds)与OS的关系

上点提到,RMA不被OS接管,而其余绝大多数内存都是被OS接管的。我们通过程序验证。

此篇幅较多,为了不偏离主题,另起介绍,请查阅此文: 验证ROM和普通内存区域(ds)与OS的关系。


9.中断过程

说了这么多,中断的过程很简单,就是CPU停下当前的指令执行,转而去执行触发中断源的中断处理程序,处理完后,又回到原来的地方继续执行接下来的指令。

那么CPU硬件成体系的处理过程的数学形式是什么样呢?

如下:

(1) (从中断信息中)取得中断类型码

(2) 标志寄存器的值入栈(因为在中断过程中要改变标志寄存器的值,所以先将其保存在栈中);

(3)设置标志寄存器的第8位TF和第9位IF的值为0(这一步的目的后面将介绍);

(4)CS的内容入栈;

(5)IP的内容入栈;

(6)从内存地址为中断类型码*4中断类型码*4+2的两个字单元中读取中断处理程序的入口地址设置IP和CS。


如果 更加简洁地描述 ,就是:

8086中断处理的步骤,标准6大步

在最后一步完成后,CPU开始执行由程序员编写的中断处理程序。

10.中断的随机性和中断程序的常驻性

由于CPU随时都可能检测到中断信息,也就是说,CPU随时都可能执行中断处理程序,所以
中断处理程序必须一直存储在内存某段空间之中。

而中断处理程序的入口地址,即中断向量,必须存储在对应的中断向量表表项中。

11.中断处理程序的模版及 iret 指令的功效

中断处理程序和子程序编写过程几乎一致,以下是常规步骤:

其中,iret 指令的功能等价为下述汇编:

pop IP 
pop CS 
popf  

iret 通常和硬件自动完成的中断过程配合使用。可以看到,在中断过程中,寄存器入栈的顺序是标志寄存器、CS、IP,而iret的出栈顺序是IP、CS、标志寄存器,刚好和其相对应,实现了用执行中断处理程序前的CPU现场恢复标志寄存器和CS、IP的工作。 iret 指令执行后,CPU回到执行中断处理程序前的执行点继续执行程序。

二、实现自己的中断处理程序

1.除法中断背景介绍

当CPU执行div等除法指令的时候,如果发生了除法溢出错误,将产生中断类型码为0中断信息CPU将检测到这个信息,然后引发中断过程,转去执行0号中断所对应的中断处理程序。我们看一下下面程序的执行结果,如图12.2所示(不同的操作系统下显示可能不同)。

;验证除法错误中断处理程序。
assume cs:codesg 

codesg segment 
start_: 
    mov ax,1000h
    mov bh,1;因为这里是8位的,所以商放在al中,余数放在ah中,但是8位的al只能表示最多FF,商的结果却是1000h,严重超出,会产生除法错误中断
    div bh

end_:
     mov ax, 4c00h 
     int 21h 
codesg ends
end start_  

除法中断处理结果

我们可以看到,触发除法中断后,确确实实发生了中断处理过程,并调用了 iret继续返回执行中断前的指令 ,注意,这里没有显示"Divide overflow"错误信息,是因为我们还没有安装好除法错误的中断处理程序。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值