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

推荐订阅源

博客园 - Franky
N
Netflix TechBlog - Medium
Google Online Security Blog
Google Online Security Blog
月光博客
月光博客
量子位
酷 壳 – CoolShell
酷 壳 – CoolShell
V
V2EX
腾讯CDC
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园 - 聂微东
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
M
MIT News - Artificial intelligence
Vercel News
Vercel News
The GitHub Blog
The GitHub Blog
Hugging Face - Blog
Hugging Face - Blog
博客园 - 【当耐特】
Apple Machine Learning Research
Apple Machine Learning Research
aimingoo的专栏
aimingoo的专栏
博客园 - 三生石上(FineUI控件)
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
MongoDB | Blog
MongoDB | Blog
H
Help Net Security
The Cloudflare Blog
Blog — PlanetScale
Blog — PlanetScale
F
Full Disclosure
G
Google Developers Blog
罗磊的独立博客
Jina AI
Jina AI
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Y
Y Combinator Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
J
Java Code Geeks
A
About on SuperTechFans
IT之家
IT之家
大猫的无限游戏
大猫的无限游戏
S
SegmentFault 最新的问题
有赞技术团队
有赞技术团队
GbyAI
GbyAI
雷峰网
雷峰网
T
The Blog of Author Tim Ferriss
The Register - Security
The Register - Security
U
Unit 42
D
Docker
Martin Fowler
Martin Fowler
L
LINUX DO - 热门话题
NISL@THU
NISL@THU
阮一峰的网络日志
阮一峰的网络日志
C
Cybersecurity and Infrastructure Security Agency CISA
博客园_首页
Google DeepMind News
Google DeepMind News

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-04-11 · via faryou的博客

前言

在8086汇编中,“中断安装中断”可以理解为通过一个自定义中断来统一管理其他中断服务程序的安装/卸载,实现中断向量的动态配置。以下是一个实现这一功能的代码,通过int 62h作为“中断安装中断”,支持注册新中断、卸载已有中断。

代码实现

; 常量定义
VECTOR_TABLE_SEG equ 0 ; 中断向量表段地址(固定为0段)
MAX_INT_NUM equ 0FFh ; 最大中断号(0-255)
 
code segment
    assume cs:code, ds:data
 
; ------------------------------
; 中断安装中断服务程序(入口:AH=功能号)
; 功能:
; AH=00h:安装中断(AL=中断号,DS:SI=中断服务程序地址)
; AH=01h:卸载中断(AL=中断号,恢复为默认处理程序)
; AH=02h:查询中断(AL=中断号,返回DS:SI=当前中断服务程序地址)
; ------------------------------
install_int proc far
    push ax
    push bx
    push cx
    push dx
    push si
    push di
    push es
    push ds ; 保存所有寄存器
    push bp
    mov bp, sp
 
    ; 检查中断号合法性(0-255)
    cmp al, MAX_INT_NUM
    ja int_end ; 中断号超出范围,不处理
 
    ; 根据功能号跳转
    cmp ah, 00h
    je install ; 安装中断
    cmp ah, 01h
    je uninstall ; 卸载中断
    cmp ah, 02h
    je query ; 查询中断
    jmp int_end
 
; ------------------------------
; 功能00h:安装中断
; 入口:AL=中断号,DS:SI=中断服务程序(段:偏移)
; 操作:将DS:SI写入中断向量表对应位置
; ------------------------------
install:
    ; 计算中断向量在表中的地址:中断号×4(每个向量占4字节:偏移2字节+段2字节)
    mov bl, al
    mov bh, 0
    shl bx, 2 ; BX = 中断号×4(向量表偏移)
 
    ; 指向中断向量表(0段)
    mov ax, VECTOR_TABLE_SEG
    mov es, ax
 
    ; 关中断,保证写入向量的原子性
    cli
    ; 保存原中断向量(用于卸载时恢复)
    mov ax, es:[bx] ; 原偏移
    mov [old_vector + bx], ax
    mov ax, es:[bx + 2] ; 原段
    mov [old_vector + bx + 2], ax
    ; 写入新中断向量(DS:SI)
    mov ax, si ; 新偏移
    mov es:[bx], ax
    mov ax, ds ; 新段
    mov es:[bx + 2], ax
    sti ; 开中断
 
    jmp int_end
 
; ------------------------------
; 功能01h:卸载中断
; 入口:AL=中断号
; 操作:恢复中断向量表中该中断号的原始值
; ------------------------------
uninstall:
    mov bl, al
    mov bh, 0
    shl bx, 2 ; BX=中断号×4
 
    mov ax, VECTOR_TABLE_SEG
    mov es, ax
 
    cli ; 关中断
    ; 恢复原向量(从保存的old_vector中读取)
    mov ax, [old_vector + bx] ; 原偏移
    mov es:[bx], ax
    mov ax, [old_vector + bx + 2] ; 原段
    mov es:[bx + 2], ax
    sti ; 开中断
 
    jmp int_end
 
; ------------------------------
; 功能02h:查询中断
; 入口:AL=中断号;返回:DS:SI=当前中断服务程序地址
; ------------------------------
query:
    mov bl, al
    mov bh, 0
    shl bx, 2 ; BX=中断号×4
 
    mov ax, VECTOR_TABLE_SEG
    mov es, ax
 
    ; 读取当前向量(偏移→SI,段→DS)
    mov si, es:[bx] ; 当前偏移
    mov dx, es:[bx + 2] ; 当前段
    mov ds, dx ; DS=当前段
 
    jmp int_end
 
; ------------------------------
; 中断结束:恢复寄存器并返回
; ------------------------------
int_end:
    pop bp
    pop ds
    pop es
    pop di
    pop si
    pop dx
    pop cx
    pop bx
    pop ax
    iret ; 中断返回
install_int endp
 
; ------------------------------
; 初始化:安装"中断安装中断"自身(int 62h)
; ------------------------------
init proc
    cli ; 关中断
    mov ax, VECTOR_TABLE_SEG
    mov es, ax
    mov di, 62h * 4 ; int 62h的向量地址:62h×4=0000:0188
    ; 保存int 62h的原向量(用于程序退出时恢复)
    mov ax, es:[di]
    mov [orig_62h_off], ax
    mov ax, es:[di + 2]
    mov [orig_62h_seg], ax
    ; 写入自定义中断服务程序地址
    mov ax, offset install_int
    stosw ; 偏移
    mov ax, cs
    stosw ; 段
    sti ; 开中断
    ret
init endp
 
; ------------------------------
; 退出:恢复int 62h的原始向量
; ------------------------------
exit proc
    cli
    mov ax, VECTOR_TABLE_SEG
    mov es, ax
    mov di, 62h * 4
    mov ax, [orig_62h_off]
    stosw
    mov ax, [orig_62h_seg]
    stosw
    sti
    ; 调用DOS退出
    mov ah, 4Ch
    int 21h
    ret
exit proc
 
; ------------------------------
; 测试用的示例中断服务程序(如键盘中断处理)
; ------------------------------
test_int proc far
    push ax
    mov ah, 02h
    mov dl, 'A' ; 触发时显示'A'
    int 21h
    pop ax
    iret
test_int endp
 
; ------------------------------
; 主程序:测试中断安装功能
; ------------------------------
main:
    mov ax, data
    mov ds, ax ; 初始化数据段
 
    call init ; 安装int 62h(中断安装中断)
 
    ; 测试1:通过int 62h安装test_int到int 63h
    mov ah, 00h ; 功能:安装
    mov al, 63h ; 目标中断号63h
    mov si, offset test_int ; 中断服务程序偏移
    ; DS已指向data,此处需将DS改为test_int所在段(即CS)
    push cs
    pop ds
    int 62h ; 调用中断安装中断
    ; 恢复DS为data段
    mov ax, data
    mov ds, ax
 
    ; 测试2:调用int 63h,验证是否安装成功
    int 63h ; 应显示'A'
 
    ; 测试3:通过int 62h查询int 63h的当前服务程序
    mov ah, 02h ; 功能:查询
    mov al, 63h ; 中断号63h
    int 62h ; 返回DS:SI=test_int地址(可自行验证)
 
    ; 测试4:通过int 62h卸载int 63h
    mov ah, 01h ; 功能:卸载
    mov al, 63h ; 中断号63h
    int 62h
 
    ; 退出程序(恢复环境)
    call exit
 
code ends
 
; 数据段:保存原始中断向量
data segment
    orig_62h_off dw 0 ; int 62h原始偏移
    orig_62h_seg dw 0 ; int 62h原始段
    ; 保存各中断的原始向量(每个中断占4字节,共256个中断)
    old_vector dw MAX_INT_NUM * 2 dup(0) ; 256×4字节=1024字节
data ends
 
    end main

代码说明

  1. 核心功能设计:自定义int 62h作为“中断安装中断”,提供三类操作:a.安装中断(AH=00h):将指定中断号与服务程序绑定,保存原始向量以便后续恢复。b.卸载中断(AH=01h):将中断号的向量恢复为安装前的原始值。c.查询中断(AH=02h):获取指定中断号当前绑定的服务程序地址。
  2. 中断向量表操作:中断向量表位于0段,每个中断号对应4字节(偏移2字节+段2字节)。通过 中断号×4 计算向量地址,操作时需关中断( cli )保证原子性,避免写入过程被其他中断打断。
  3. 自安装与恢复:程序初始化时,将自身的 install_int 服务程序注册到int 62h,并保存int 62h的原始向量;程序退出时恢复原始向量,避免破坏系统环境。
  4. 测试逻辑:主程序通过int 62h安装一个测试中断(int 63h),调用该中断验证效果,再查询、卸载,完整演示中断安装中断的使用流程。