惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Martin Fowler
Martin Fowler
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
A
About on SuperTechFans
Apple Machine Learning Research
Apple Machine Learning Research
The Register - Security
The Register - Security
Vercel News
Vercel News
H
Hackread – Cybersecurity News, Data Breaches, AI and More
人人都是产品经理
人人都是产品经理
MyScale Blog
MyScale Blog
云风的 BLOG
云风的 BLOG
博客园_首页
U
Unit 42
T
Tailwind CSS Blog
G
GRAHAM CLULEY
F
Full Disclosure
V
Vulnerabilities – Threatpost
T
Tenable Blog
月光博客
月光博客
P
Privacy & Cybersecurity Law Blog
P
Privacy International News Feed
K
Kaspersky official blog
Scott Helme
Scott Helme
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
N
News and Events Feed by Topic
T
The Exploit Database - CXSecurity.com
N
News and Events Feed by Topic
有赞技术团队
有赞技术团队
Recent Commits to openclaw:main
Recent Commits to openclaw:main
L
LINUX DO - 最新话题
Recorded Future
Recorded Future
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Help Net Security
Help Net Security
The GitHub Blog
The GitHub Blog
Cisco Talos Blog
Cisco Talos Blog
SecWiki News
SecWiki News
P
Proofpoint News Feed
Security Latest
Security Latest
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
罗磊的独立博客
S
Security Affairs
M
MIT News - Artificial intelligence
L
LINUX DO - 热门话题
美团技术团队
Simon Willison's Weblog
Simon Willison's Weblog
T
Threat Research - Cisco Blogs
Stack Overflow Blog
Stack Overflow Blog
Forbes - Security
Forbes - Security
Hugging Face - Blog
Hugging Face - Blog
博客园 - Franky
V
Visual Studio Blog

faryou的博客

出租车上的对话 faryou的博客-告别小高一 faryou的博客-中考 · 竞赛 · 生活 · 思考 5月月考 - faryou的博客 - 日记 faryou的博客-五一回老家 【汇编 - 功能】中断安装中断实现 【汇编&硬件】时钟中断的具体实现 faryou的博客-这些年,我不再看《熊出没》 【汇编&硬件】关机中断的具体实现 【汇编&硬件】网络连接相关中断的具体实现 faryou的博客-年初小记 【汇编&硬件】鼠标控制中断的具体实现 【汇编&硬件】声音输出中断的具体实现 【汇编&硬件】屏幕输出中断的具体实现 【汇编&硬件】磁盘读取中断的具体实现 【汇编&硬件】键盘读取中断的具体实现 【汇编】汇编环境的搭建及Debug的使用教程 【汇编】漫谈:学习汇编后的一些思考 faryou的博客-关于本站即日起实行“一站三体”运营制度 【汇编基础教程】完结篇 写在最后:前言 【汇编基础教程】使用BIOS的中断实现键盘输入及磁盘I/O 【汇编基础教程】端口 【汇编基础教程】标志寄存器 【汇编基础教程】再谈栈 【汇编基础教程】段 【汇编基础教程】来存一些数据! 【汇编基础教程】寄存器和内存&一些基本命令的说明 【汇编基础教程】来写个“函数” 【汇编基础教程】更灵活的定位内存 【汇编基础教程】理解一下[bx]和loop指令 【汇编基础教程】跳一跳! faryou的博客-我的竞赛经历&对人生的一些思考 faryou的博客-关于现在中小学计算机课的一些想法及思考 faryou的博客-2025年度总结 faryou的博客-临平山下十五年 faryou的博客-Windows 10即将停止支持,谈谈自己从小到大用电脑的感受 faryou的博客-谈谈一名10后的怀旧情怀 【汇编基础教程】8086CPU工作原理 【C语言】指针的理解与应用 【算法教程】【C/C++】DP(动态规划):区间DP——程序设计思路与代码实现 【算法教程】【C/C++】BFS(广度优先搜索)——程序设计思路与代码实现 【算法教程】【C/C++】DFS(深度优先搜索)——程序设计思路与代码实现 【算法教程】【C/C++】单源最短路径——程序设计思路与代码实现 【算法教程】【C/C++】最小生成树——程序设计思路与代码实现 【算法教程】【C/C++】并查集——程序设计思路与代码实现 【算法教程】【C/C++】DP(动态规划):背包DP——程序设计思路与代码实现 【算法教程】【C/C++】DP(动态规划):简单动规问题——程序设计思路与代码实现 【算法教程】【C/C++】递推——程序设计思路与代码实现 【算法教程】【C/C++】三分算法——程序设计思路与代码实现 【算法教程】【C/C++】二分答案——程序设计思路与代码实现 【算法教程】【C/C++】二分查找——程序设计思路与代码实现 【算法教程】【C/C++】贪心算法——程序设计思路与代码实现 【算法教程】【C/C++】基础数学:快排——程序设计思路与代码实现 【算法教程】【C/C++】基础数学:快速幂——程序设计思路与代码实现 【算法教程】【C/C++】基础数学:进制转换——程序设计思路与代码实现 一文弄懂C++中的自定义函数 faryou的博客-2024年度总结
【汇编基础教程】中断
作者: faryou · 2026-01-30 · via faryou的博客

前言

中断是CPU中用于处理其内外突发情况的一种机制。CPU执行完当前的指令后,检测到CPU内部或外部传送的一种特殊信息(称“中断信息”),立刻处理这些信息,处理方式即立刻跳转到中断的对应处理程序,执行完这段程序后再返回。中断机制常在CPU及操作系统提供磁盘操作、键盘输入、屏幕输出等处理程序时使用,可以视为早期16位操作系统的一种“API”,本质是一种具有特殊触发条件的函数。下面我们将详细学习几种种情况引起的中断,以及编写程序时如何利用中断机制。

中断的过程

当8086CPU收到中断信息后,处理过程如下:

(1)取得中断类型码
(2)pushf
(3)修改TF、IF值为0
(4)CS、IP入栈
(5)进入中断程序(通过修改CS、IP的值)
(6)恢复CS、IP、标志寄存器的值(从而返回程序)

需要注意的是,如果进入中断的前一条指令修改了ss寄存器的值,那么即使触发了中断条件,也不会进入中断程序。因为ss:sp是一个整体,若ss:sp值不对应则会引起中断之后的错误,所以CPU提供了这一特性。

中断向量表

8086CPU支持256个中断,为此,规定内存0000:0000~0000:03FF的1024个单元存放0~255号中断的入口,从而建立中断类型码(即中断的编号)与中断程序之间的一一映射关系。其中,每两个字存放一个中断处理程序的地址,高位存放中断处理程序的偏移地址,低位存放其段地址。由此,不难理解,当CPU获得中断类型码N后,即通过设置CS:IP的值为(N4):(N4+2)跳转到中断处理程序,中断结束后再返回原来的位置。

内中断

内中断的中断信息由CPU内部产生。对8086CPU,当发生如下四种情况时,会引起内中断:

(1)除法错误(执行div等除法指令时,除数为0)
(2)单步执行(使用debug的时候)
(3)执行into指令
(4)执行int指令

下面将分别介绍说明~

除法错误中断

除法错误中断为0号中断,用于处理div等除法指令除数为零的错误。让我们执行下面的程序:

mov ah,0
mov bh,1
div bh

可以看到,屏幕上输出了“Divide overflow!”,但我们并没有写输出字符串的程序。原因是:这里出现了除数为0的错误,从而引发0号中断,0号中断处理程序的功能即输出字符串“Divide overflow”。

单步中断

单步中断为1号中断,用于提供Debug的单步执行功能。在使用Debug调试时,我们经常需要逐条调试代码(即使用T命令),单步中断就是提供这一功能的中断。其触发条件为TF值为1。这样我们就很容易理解为什么进入中断之前要设置TF值为0了:如果进入中断前TF值为1,那么执行中断处理程序的第一条指令后,CPU检测到TF值为1,触发单步中断,进入其中断处理程序;执行完中断处理程序之后,又检测到TF值为1,又重新执行1号中断的第一条指令;陷入死循环。

into指令引发内中断

into指令检测上一条计算指令是否发生了溢出,若是,则进入4号中断。我们可以通过修改4号中断对应的程序,实现需要的功能(后面会详细介绍)。into指令的格式:

into

int指令引发内中断

int指令的功能是引发中断过程,我们前面所说的中断承载的“API”功能即主要通过int指令实现。其使用格式:

int 中断类型码

操作系统把“API”以中断形式写到内存里,应用程序通过int指令即可方便地调用。同时,int指令也可以用于不同程序间的数据互通,这对于早期的单任务操作系统尤为重要。我们之前写程序最后总有一句:

int 21h

中断类型码21H对应的中断功能即为:返回操作系统。这为应用程序提供了快速返回操作系统的方式。
接下来我们学习如何自己利用中断机制~

自己编写中断程序

我们来实现一个40h中断,包括如下功能:

(0)清理屏幕
(1)显示日期
(2)显示时间

按照汇编的惯例,一个中断里常有多个功能,在调用其中一个子功能时,一般用ah寄存器传递功能号。我们之前的程序中:

mov ax,4c00h

就是传递21h中断的参数。接下来考虑我们这个中断处理程序的实现有哪些步骤。很显然,我们需要如下的步骤:

(1)用到的寄存器入栈保存
(2)中断处理程序
(3)寄存器出栈
(4)返回

中断返回一般用iret指令,其功能相当于:

pop IP
pop CS
popf

中断程序也占用空间。我们这里只是进行练习,所以只要别让代码影响到操作系统即可。所以我们直接扔到闲置的中断向量表区,即0000:0200~0000:03FF区域。
下面开始编写~

assume cs:codesg

;安装程序
codesg segment
setup:
  mov ax,cs
  mov ds,ax
  mov si,offset code
  mov ax,0
  mov es,ax
  mov di,200h

  mov cx,offset codeend-offset code
  cld
  rep movsb

  mov ax,0
  mov ds,ax
  mov word ptr [4*40h],200h
  mov word ptr [4*40h+2],0

  mov ax,4c00h
  int 21h

;中断处理程序
code:
  cmp ah,2
  jae codeback
  mov bx,ax
  shl bx
  jmp word ptr codetable[bx]
run0:
  push cx
  mov cx,4000
  push ax
  push ds
  mov ax,0b800h
  mov ds,ax
  rep mov byte ptr [cx],0
  pop ds
  pop ax
  pop cx
run1:
  push cx
  mov cx,3
  push ax
  push bx
  push dx
  mov ax,cs
  mov ds,ax
  mov ax,0b800h
  mov es,ax
  mov bx,14
run1_loop:
  mov al,codedata1[cx]
  out al,70h
  in 71h,al
  mov ah,al
  shr ah,4
  and al,00001111b
  add al,30h
  add ah,30h
  mov byte ptr es:[bx],al
  sub bx,2
  mov byte ptr es:[bx],ah
  sub bx,4
  loop run1_loop
  mov byte ptr es:[4],'/'
  mov byte ptr es:[10],'/'
  pop dx
  pop bx
  pop ax
  pop cx
  iret
run2:
  push cx
  mov cx,3
  push ax
  push bx
  push dx
  mov ax,cs
  mov ds,ax
  mov ax,0b800h
  mov es,ax
  mov bx,14
run2_loop:
  mov al,codedata2[cx]
  out al,70h
  in 71h,al
  mov ah,al
  shr ah,4
  and al,00001111b
  add al,30h
  add ah,30h
  mov byte ptr es:[bx],al
  sub bx,2
  mov byte ptr es:[bx],ah
  sub bx,4
  loop run2_loop
  mov byte ptr es:[4],':'
  mov byte ptr es:[10],':'
  pop dx
  pop bx
  pop ax
  pop cx
  iret
codeback:iret
codetable dw run0,run1,run2
codedata1 db 9,8,7
codedata2 db 4,2,0
codeend:nop
codesg ends
end setup

执行过上述程序之后,40h号中断即安装进了系统,我们执行下面的指令即可调用:

mov ah,1;这里以1号功能为例,会显示日期
int 40h

外中断

外中断是用于外部硬件引发的中断,通常用来处理硬件相关的信息。外部设备全部通过端口接入PC机,而外中断就是在某些端口的信息送达CPU时引发的中断。下面我们来了解外中断。
首先,外接设备多种多样,而主板本身并没有这么多的端口来接入各种外部设备。况且对于外中断,在一般情况下都应该立刻作出反应。因此,我们需要一个中介,连接主板与外部设备,并向CPU发送外接设备的中断类型码。这个设备就是中断控制芯片。我们以8259A中断控制芯片为例(因为它是8086机上最常见的)。8259A上有8个端口,以接入8种不同的设备。当外部中断(如键盘输入)发生时,它通过预先设定好的外部中断-中断类型码映射关系,找到键盘中断对应的信息,并传递给CPU。然后,CPU执行中断处理程序。
BIOS中的9号中断有基本的键盘处理程序,以进行基本的输入输出处理,包括:

(1)读入扫描码
(2)如果该扫描码代表字符键,刚将该扫描码与对应的ASCLL码送入BIOS键盘缓冲区(该缓冲区由16h号中断管理);如扫描码代表控制键或切换键,则将其转变为状态字节,写入内存的0040:0017单元。
(3)完成对硬件系统的应答

其中最后一步是普遍适用于所有外中断的。它向8259A发送中断处理完毕的信息,从而继续工作。其实现如下:

mov al,0x20
out 0x20,al
out 0xa0,al
iret

这段代码向8259A发送EOI信息,以使其继续工作。
之后的内容我们会进一步学习各种硬件中断的具体实现,这里只作基本了解~