持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第14天,点击查看活动详情
前言
点赞再看,养成习惯!
今天的内容是CPU的内中断,内容不多,以理解为主!
一、 中断概述
1.1 什么是中断
中断就是计算机在正常处理程序的过程中,当发现某种异常事件或某种外部请求时,处理器会暂停执行当前程序转而执行异常事件处理或外部事件处理。当处理结束后,继续执行之前暂停的程序。
1.2 什么是中断信息
当CPU检测到由内部或者外部产生的某种信息后暂停当前程序并立即处理所接收到的信息时,这种信息就被称为中断信息。
1.3 什么是内中断
由内部产生的中断信息就被称为内中断。
1.4 内中断的产生
对于8086CPU产生内终端的情况一共有四类:
- 除法错误
- 单步执行(如Dosbox的T指令)
- 执行into指令(后续会讲)
- 执行int指令(后续会讲)
而针对这四类中断信息,CPU还需要一个标识进行区分,这个标识就被我们称为中断类型码。中断类型码为一个字节型数据,可以表示256中中断信息的来源,而这些产生中断信息的时间也被我们称为中断源。
上述四种类型对应的中断类型码如下:
| 中断类型 | 中断类型码 |
|---|---|
| 除法错误 | 0 |
| 单步执行 | 1 |
| 执行into指令 | 4 |
| 执行int指令 | int n 中的n为字节型立即数 |
二、 中断原理
2.1 原理推断
刚刚我们讲过中断是CPU暂停当前程序去处理异常事件或者外部请求,处理结束后再继续执行暂停事件的现象。 根据这段描述我们可以将中断简单的分为三个过程:
- 暂停当前程序(保存当前指令地址及Flag寄存器的值)
- 跳转执行新请求
- 返回暂停程序
这个程序过程是不是有的小伙伴很眼熟?是不是很像我们之前讲过的模块化程序设计 中的代码模板?
程序段A:
。。。
call 程序段B
程序段B:
。。。
ret
而这其中的call 程序段B 也就等于jmp 段地址:偏移地址 ,其原理就是同时修改CS:IP 寄存器的值,也就是说我们所说的中断跳转无非就是通过修改CS:IP的指针指向带达到让CPU跳转的目的。
2.2 中断向量表
那么我们该如何修改CS:IP的值呢?换句话说就是我们依据什么去修改CS:IP的值呢?这个就要提到一个具有导向作用的概念中断向量表。 我们刚刚讲过CPU用8位的中断类型码判断所需要进行的中断类型,而对应的每一种中断类型在内存单元中都保存了一段数据,该数据指向了处理当前中断类型的程序指令,将这个步骤简化一下就是:
- CPU获取中断类型码
- 通过中断类型码查找中断向量表
- 中断向量表中保存着指令地址
- 修改CS:IP指向新的指令地址
- 运行中断程序
这里有个概念需要细化,我们提到的中断向量表并不是一个像字典一样的目录表格,而是计算机将某一连续的内存空间中预先存储指令地址数据。以8086CPU举例,计算机将内存0000:0000 到 0000:03FF 这1024个连续内存单元中存放了指令地址数据。而我们的CS:IP仅需要按照:
CS = 中断类型码 * 4 +2 , IP= 中断类型码*4 进行跳转获取数据即可。
2.3 中断处理程序模拟
当我们清楚了中断向量表的使用原理后,我们可以进一步的推到中断程序的底层实现:
- 获取中断类型码N
pushfTF = 0IF=0push CSpush IPIP = N*4CS = N*4+2pop cspop ippopf
这里的pop cs pop ip popf 三个指令可以概括为一个指令iret 。
结语
今天的内容就到此结束了,有疑问的小伙伴欢迎评论区留言或者私信博主,博主会在第一时间为你解答。
码字不易,感到有收获的小伙伴记得要关注博主一键三连,不要当白嫖怪哦~
如果大家有什么意见和建议请评论区留言或私聊博主,博主会第一时间反馈的哦