首页 > 编程知识 正文

若某计算机有5个中断源(计算机中断)

时间:2023-05-05 17:17:37 阅读:96132 作者:3224

中断,英文叫Interrupt,在计算机世界无处不在,任何工作都离不开中断。可以说整个计算机系统都是由中断驱动的。那么什么是中断呢?简单来说就是CPU停止当前的工作任务去处理其他事情,处理完之后再回来继续执行之前的任务。这个过程是一个中断。

本文旨在进一步揭示中断机制,阐明中断过程,并从中断分类、中断描述符表、中断控制器、中断过程等方面介绍中断。详细的思维导图如下:

中断分类

00-1010 1.可屏蔽中断:中央处理器通过INTR线请求的中断主要来自硬盘、打印机、网卡等外部设备。这种中断不会影响系统运行,可以随时处理甚至不处理,所以称为可屏蔽中断。

2.不可匹配中断:通过NMI线向CPU请求的中断,如电源故障、硬件电路故障等。这里非屏蔽的意思不是不能屏蔽,不建议屏蔽,而是问题太大不能屏蔽。

注意:INTR和NMI都是CPU的管脚。

00-1010 1.陷阱:是一种有意的、预先安排的异常事件,通常是编程时有意设置的陷阱指令。陷阱指令执行后,CPU会调用特定程序进行相应处理,处理后返回陷阱指令的下一条指令。如系统调用、程序调试功能等。

虽然我们平时写程序的时候好像没有设置陷阱,是因为我们通常使用的高级语言对于底层指令有太多的抽象封装层,看不到底层实现,但是它其实是存在的。例如,对于printf函数,最低实现中将有一条int0x80指令,这是一条trap指令,系统调用将使用0x80中断进行。

2.故障:故障是CPU在导致故障的指令执行时,检测到的一种意外事件,但执行尚未完成。错误由错误处理程序处理。如果可以纠正错误,控制将返回到导致故障的指令,即CPU将再次执行该指令。如果你不能处理它,你将报告一个错误。

的通病是缺页,当CPU引用的虚拟地址对应的物理页面不存在时,就会出现这种情况。缺页异常可以纠正。有一个特殊的缺页处理程序,它会将丢失的物理页从磁盘重新定位到主内存。然后,当导致故障的指令被再次执行时,它可以被成功执行。

3.终止:执行指令过程中出现致命错误,无法修复,程序无法继续运行,只能终止,通常是因为一些硬件错误。终止处理程序不会将控制权返回给原程序,而是直接终止原程序。

中断描述符表类似于全局描述表。与GDT不同,IDT可以存储四种描述符:任务门描述符、陷阱门描述符、调用门描述符和中断门描述符。

这里,我们只介绍中断门描述符。除了任务门,这四个描述符是相似的。中断门也是最常用的一种。例如,Linux的系统调用是利用中断门实现的。

中断描述符

中断描述符的结构如上,重要的字段和属性都做了标记,理解一下就好,不需要深究每一位的具体含义。

中断向量号

在介绍中断向量号之前,我们首先介绍段选择器的概念。所谓的段选择器是段寄存器的值。段选择器的高13位是全局描述符表的索引号,其他位置是属性位,这就像用数组下标索引数组元素一样。

至于中断向量号,该函数相当于段选择器的高13位,用于索引IDT的相对中断描述符,但没有类似于段选择器的相应结构。

中断矢量表的一部分,需要理解的部分如下图所示:

中断描述符表寄存器IDTR

IDTR也类似于GDTR,存储48位数据信息,w

指令将其加载到IDTR寄存器,使得CPU知道IDT在哪。

每个独立运行的外设都可以是一个中断源,能够向CPU发送中断请求,为了方便管理和减少引脚数目,设立了中断控制器,让所有的可屏蔽中断都通过INTR信号线与CPU进行交流。

中断控制器中较为流行的是Intel 8259A芯片,下面对8259A作简单介绍:

级联

单个8259A芯片只有8根中断请求信号线(IRQ0, IRQ1, … , IRQ7),这是不够用的,所以采用多个8259A芯片。将它们如下图一样像串联的方式组合起来,这种组合方式就叫做级联。

级联时只能有一个主片,其余的均为从片,最多可级联9个,即最多支持64个中断。为什么不是8 * 9 = 72个呢?从上图可以看出级联时后面的芯片会占用前面芯片的一个IRQ接口,而最后一个8259A没有其他人占用,所以8259A的个数和支持的中断数关系为7n + 1。

8259A的一些功寄存器和功能部件

1、IMR:Interrupt Mask Register,中断屏蔽寄存器,其中的每个位标志着一个外设,1表示屏蔽该外设,0表示中断允许。

2、IRR:Interrrupt Request Register,中断请求寄存器,请求中断的外设在IRR对应的位 值为1。当有多个中断请求时,IRR寄存器中多位将会置1,相当于维持了一个请求中断的队列。

3、ISR:In_Service Register,中断服务寄存器,正在进行处理的中断在ISR对应的位值为1。

4、PR:Priority Resolver,优先级裁决器,用于从IRR中挑选一个优先级最大的中断。(IRQ接口号小的优先级大)。

中断过程

中断请求

1、当外设发出中断信号后,信号被送入8259A;

2、8259A检查IMR寄存器中是否屏蔽了来自该IRQ的信号,若IMR寄存器中对应的位为1,表示屏蔽了IRQ代表的中断,则丢掉此中断信号,若IMR寄存器中对应的位为0,表示未屏蔽此中断,则将IRR寄存器中与此中断对应的位 置1。

3、PR优先级裁决器从IRR寄存器中挑选一个优先级最大的中断,然后8259A向CPU发送INTR信号。

中断响应

1、CPU收到INTR信号后便知道有新的中断了,在执行完当前指令后,向8259A发送一个中断回复信号。

2、8259A收到回复信号后,将选出来的优先级最大的中断在ISR寄存器中相应的位 置1,表示该中断正在处理,同时将此中断在IRR寄存器中相应的位 置0,相当于将此中断从中断请求队列中去掉。

3、CPU再次向8259A发送INTR信号,表示想要获取中断向量号。

4、8259A通过数据总线向CPU发送中断向量号,中断向量号 = 起始向量号 + IRQ接口号,一般起始向量号为32,从中断向量表可看出0—31已经被占用,后面的32—127是分配给可屏蔽中断的,所以此处外设的中断设置的起始向量号便为32。

保护现场——压栈

1、CPU据中断向量号去IDT中获取中断描述符,取出选择子中的DPL与当前特权级CPL进行比较,若特权级发生变化,则需要切换栈。(不同特权级有着不同的栈,如Linux使用了0, 3特权级,则有两个栈,一个内核栈,一个用户栈)

2、于是处理器临时保存当前的旧栈SS和ESP的值,从TSS(每一个任务有一个TSS结构,其中保存着不同特权级栈的SS和ESP值)中获取与DPL特权级同的栈信息加载到SS和ESP寄存器。再将旧栈SS和ESP的值压入新栈中。若没有特权级变化,则跳过此步骤。

3、压入程序状态信息,即EFLAGS寄存器

4、压入断点,即返回地址,即当前任务的CS,EIP值。

5、若该中断有错误码,压入错误码

定位中断服务程序

直接先上流程图:

具体步骤如下:

1、据中断向量号去IDT中索引中断描述符,具体操作:取出IDTR中的IDT地址,加上中断向量号 * 8,得到的地址指向所要的中断描述符。

2、据中断描述符中的段选择子去GDT中索引段描述符,具体操作:取出GDTR中的GDT地址。加上段选择子高13位 * 8, 得到的地址为中断处理程序所在段的段基址。

3、上一步得到的段基址加上段描述符中的段内偏移量得到的地址变为中断服务程序的地址。

中断处理过程

中断的实际处理过程就是执行中断处理程序,Linux将中断处理程序分为上下两部分,需要紧急处理立即执行的归为上半部,不那么紧急的归为下半部。

这便涉及到了开关中断的问题。开中断,即EFLAGS的IF位置1,表示允许响应中断;关中断,即EFLAGS的IF位置0,表示不允许响应中断。

1、上半部分是刻不容缓的,需要立即执行的部分,所以要在关中断的状态下执行。

2、而下半部分不那么紧急,在开中断的情况下进行,如果此时有新的中断发生,当前中断处理程序便会换下CPU,CPU会另寻时间重新调度,完成整个中断处理程序。

中断返回——出栈

中断返回就是出栈的过程,将第三步保护现场压入栈中的信息弹出。

1、有错误码弹出错误码。

2、此时的栈顶指针ESP应指向EIP_old,剩余栈中的信息使用iret指令弹出,CPU执行到iret指令时再次检查和比较特权级是否变化。

3、弹出EIP_old, CS_old

4、若特权级变化,将ESP_old, SS_old, 加载到ESP,SS寄存器。

至此,中断已返回,中断也已处理。

上述的中断过程是我根据资料照着自己的理解分为了6步,每步又有许多微操作,可能跟某些书籍资料等所划分的步骤不同,甚至一些微操作的顺序也不太一样,比如说中断处理时什么时候关中断,我查阅了许多资料和书籍,讲述得都有区别。

不同操作系统在中断方面的实现有所不同,但总体来说都会经历上述的步骤,可能细微之处略有差别,却也不影响我们了解中断的过程。

中断是操作系统重要的机制,没有中断,操作系统什么也干不了,没法输入没法输出,不能管理硬件资源,也不能向上层应用提供服务。而且操作系统本身就像是一个死循环,等待事件发生需求来临,然后为其提供服务解决问题。而这事件的发生与处理就是靠中断机制来控制的,所以说中断对于操作系统来说有着举足轻重的作用,而我们也有必要了解中断,理清中断的过程。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。