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

推荐订阅源

cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
C
CERT Recently Published Vulnerability Notes
GbyAI
GbyAI
Google DeepMind News
Google DeepMind News
C
CXSECURITY Database RSS Feed - CXSecurity.com
AWS News Blog
AWS News Blog
V
Vulnerabilities – Threatpost
T
Tenable Blog
P
Proofpoint News Feed
C
Check Point Blog
T
The Exploit Database - CXSecurity.com
F
Full Disclosure
P
Privacy & Cybersecurity Law Blog
美团技术团队
U
Unit 42
C
Cyber Attacks, Cyber Crime and Cyber Security
阮一峰的网络日志
阮一峰的网络日志
Simon Willison's Weblog
Simon Willison's Weblog
量子位
AI
AI
Spread Privacy
Spread Privacy
Help Net Security
Help Net Security
Know Your Adversary
Know Your Adversary
IT之家
IT之家
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
P
Proofpoint News Feed
Recent Commits to openclaw:main
Recent Commits to openclaw:main
L
LangChain Blog
I
Intezer
T
The Blog of Author Tim Ferriss
爱范儿
爱范儿
月光博客
月光博客
Recorded Future
Recorded Future
O
OpenAI News
WordPress大学
WordPress大学
Microsoft Security Blog
Microsoft Security Blog
J
Java Code Geeks
Y
Y Combinator Blog
Engineering at Meta
Engineering at Meta
S
Security @ Cisco Blogs
Recent Announcements
Recent Announcements
P
Privacy International News Feed
NISL@THU
NISL@THU
MongoDB | Blog
MongoDB | Blog
W
WeLiveSecurity
B
Blog RSS Feed
Blog — PlanetScale
Blog — PlanetScale
博客园 - Franky
Cyberwarzone
Cyberwarzone
H
Hacker News: Front Page

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

前言

int 8h是8086系统中由8253定时器通道0触发的系统时钟中断,主要用于维持系统时间、触发定时任务等,默认由BIOS或DOS内核实现。以下是一个模拟int 8h核心功能的自定义中断服务程序,包含系统时间更新、定时中断处理等功能。

代码实现

; 常量定义
TIMER_CTRL_PORT equ 43h ; 8253定时器控制端口
TIMER_CH0_PORT equ 40h ; 定时器通道0端口
BASE_FREQ equ 1193180 ; 定时器基准频率(Hz)
CLK_TICKS_PER_SEC equ 18 ; 每秒时钟滴答数(DOS默认,18.2次/秒)
BIOS_TIME_SEG equ 0040h ; BIOS时间存储段地址
BIOS_TIME_OFF equ 006Ch ; BIOS时间存储偏移(dword:自午夜起的滴答数)
 
code segment
    assume cs:code, ds:data

; 自定义int 8h中断服务程序
; 功能:
; 1. 定时器中断处理(维持系统时钟)
; 2. 更新BIOS时间(滴答数累计)
; 3. 调用原int 8h服务程序(链式调用,保留系统功能)

int8_proc proc far
    push ax
    push bx
    push cx
    push dx
    push si
    push di
    push es
    push ds ; 保存所有寄存器

    ; 步骤1:更新BIOS系统时间(滴答数)
    mov ax, BIOS_TIME_SEG
    mov es, ax ; ES指向BIOS数据段
    inc dword ptr es:[BIOS_TIME_OFF] ; 滴答数+1(每中断一次加1)

    ; 步骤2:触发int 1Ch(用户定时中断,默认无操作,可由用户扩展)
    int 1Ch ; 调用用户定时中断钩子
 
    ; 步骤3:发送EOI信号给8259A中断控制器,允许后续中断
    mov al, 20h ; EOI命令
    out 20h, al ; 发送给主8259A

    ; 步骤4:链式调用原int 8h服务程序(保留系统默认功能)
    call dword ptr cs:[orig_int8] ; 调用原int 8h
 
    ; 恢复寄存器并返回
    pop ds
    pop es
    pop di
    pop si
    pop dx
    pop cx
    pop bx
    pop ax
    iret ; 中断返回
int8_proc endp
 
; 初始化定时器通道0(设置中断频率)
; 频率 = BASE_FREQ / 计数初值 → 计数初值 = BASE_FREQ / 目标频率
init_timer proc
    ; 计算计数初值(18.2Hz对应的初值:1193180 / 18.2 ≈ 65536)
    mov ax, 0 ; 计数初值=65536(0000h,16位最大值)
    ; 配置定时器通道0:模式3(方波输出),16位计数
    mov al, 00110110b ; 控制字:通道0,读写高8+低8,模式3,二进制
    out TIMER_CTRL_PORT, al
    ; 写入计数初值(65536的低8位和高8位均为00h)
    mov al, 0
    out TIMER_CH0_PORT, al ; 低8位
    out TIMER_CH0_PORT, al ; 高8位
    ret
init_timer endp
 
; 安装自定义int 8h中断(替换系统默认中断)
install_int8 proc
    cli ; 关中断,防止安装过程被打断
    mov ax, 0
    mov ds, ax ; DS指向中断向量表(0段)
    ; 保存原int 8h中断向量(段:偏移)
    mov ax, ds:[8*4] ; 原偏移
    mov word ptr cs:[orig_int8], ax
    mov ax, ds:[8*4 + 2] ; 原段
    mov word ptr cs:[orig_int8 + 2], ax
    ; 写入自定义中断服务程序地址到int 8h向量
    mov ax, offset int8_proc
    mov ds:[8*4], ax ; 偏移
    mov ax, cs
    mov ds:[8*4 + 2], ax ; 段
    sti ; 开中断
    ret
install_int8 end

; 恢复原int 8h中断向量(程序退出时调用)
restore_int8 proc
    cli
    mov ax, 0
    mov ds, ax
    ; 恢复原向量
    mov ax, word ptr cs:[orig_int8]
    mov ds:[8*4], ax
    mov ax, word ptr cs:[orig_int8 + 2]
    mov ds:[8*4 + 2], ax
    sti
    ret
restore_int8 endp

; 测试用的int 1Ch用户定时中断(每秒显示一次)
int1c_proc proc far
    push ax
    push bx
    push cx
    push dx
    push ds
    mov ax, data

    mov ds, ax ; 初始化数据段
    ; 每CLK_TICKS_PER_SEC次中断(约1秒)执行一次
    inc word ptr [tick_count]
    mov ax, [tick_count]
    cmp ax, CLK_TICKS_PER_SEC
    jne int1c_end

    ; 1秒到,显示字符'.'
    mov ah, 02h
    mov dl, '.'
    int 21h
    mov word ptr [tick_count], 0 ; 重置计数器

int1c_end:
    pop ds
    pop dx
    pop cx
    pop bx
    pop ax
    iret
int1c_proc endp

; 安装int 1Ch用户定时中断
install_int1c proc
    cli
    mov ax, 0
    mov ds, ax
    ; 保存原int 1Ch向量
    mov ax, ds:[1Ch*4]
    mov word ptr cs:[orig_int1c], ax
    mov ax, ds:[1Ch*4 + 2]
    mov word ptr cs:[orig_int1c + 2], ax
    ; 写入自定义int 1Ch处理程序
    mov ax, offset int1c_proc
    mov ds:[1Ch*4], ax
    mov ax, cs
    mov ds:[1Ch*4 + 2], ax
    sti
    ret
install_int1c endp

; 恢复原int 1Ch中断
restore_int1c proc
    cli
    mov ax, 0
    mov ds, ax
    mov ax, word ptr cs:[orig_int1c]
    mov ds:[1Ch*4], ax
    mov ax, word ptr cs:[orig_int1c + 2]
    mov ds:[1Ch*4 + 2], ax
    sti
    ret
restore_int1c proc

; 主程序:安装中断并测试
main:
    mov ax, data
    mov ds, ax ; 初始化数据段

    ; 安装int 8h和int 1Ch中断
    call install_int8
    call install_int1c
    call init_timer ; 初始化定时器

    ; 等待用户按键退出
    mov ah, 01h
    int 21h ; 等待按键

    ; 恢复系统中断
    call restore_int1c
    call restore_int8

    ; 程序退出
    mov ah, 4Ch
    int 21h

; 数据区(在代码段中定义,避免额外段操作)
orig_int8 dd 0 ; 原int 8h中断向量(段:偏移)
orig_int1c dd 0 ; 原int 1Ch中断向量
tick_count dw 0 ; 用于int 1Ch的滴答计数器


code ends
data segment
data ends ; 数据段仅作占位

    end main

代码说明

  1. 核心功能:自定义int 8h中断服务程序模拟了系统时钟中断的核心功能,包括:a.每触发一次中断,更新BIOS数据区的滴答数(自午夜起的累计中断次数,用于系统时间计算)。b.调用int 1Ch(用户定时中断钩子),允许用户扩展定时任务(如示例中每秒显示一个点)。c.发送EOI信号给8259A中断控制器,确保后续中断能被响应。d.链式调用原int 8h服务程序,保留系统默认功能(如DOS的时间管理)。
  2. 定时器配置:8253定时器通道0被配置为模式3(方波输出),计数初值为65536,对应中断频率约18.2次/秒(DOS系统默认),计算公式为:计数初值=基准频率(1193180Hz)/目标频率(18.2Hz≈65536。
  3. 中断安装与恢复:a.安装时保存原int 8h和int 1Ch的中断向量,将自定义处理程序地址写入中断向量表。b.程序退出前恢复原向量,避免破坏系统正常运行。
  4. 测试逻辑:主程序安装中断后,通过int 1Ch的自定义处理程序实现每秒显示一个点,直观展示定时中断的效果,按任意键退出并恢复系统环境。