
























int 9h是8086系统中键盘中断的中断服务程序,用于处理键盘输入。其功能包括读取键盘扫描码、处理特殊键(如Shift、Ctrl等)、将扫描码转换为ASCII码以及设置键盘缓冲区等。它与面向用户的int 16h相互配合。前面我们说过int 9h涉及到硬件的处理,所以当时没有尝试自己编写。下面我们尝试自己实现这个中断。
; 定义段寄存器
code segment
assume cs:code
; 键盘中断服务程序(替代int 9h)
keyboard_int proc far
push ax
push bx
push cx
push dx
push si
push di
push es
push ds ; 保存所有寄存器状态
; 1. 读取键盘扫描码(从端口60h读取)
in al, 60h ; 读取扫描码到AL(通码:按键按下,断码:按键松开,断码=通码+80h)
; 2. 向8259A发送中断结束信号(EOI),允许后续中断
mov al, 20h ; EOI命令字
out 20h, al ; 发送到主8259A
; 3. 处理扫描码(此处简化处理:仅响应部分按键,忽略断码和特殊键)
cmp al, 80h ; 判断是否为断码(若AL>=80h,说明按键松开,不处理)
jae int_end ; 是断码则直接结束
; 4. 扫描码转ASCII码(简化映射表,仅举例常用键)
mov bx, offset scancode_to_ascii ; BX指向映射表
xlat ; AL = [BX + AL](根据扫描码获取ASCII码,0表示无对应ASCII)
; 5. 若有有效ASCII码,存入键盘缓冲区(简化,实际需检查缓冲区状态)
cmp al, 0
je int_end ; 无对应ASCII,结束
; 此处仅演示,实际缓冲区操作需更复杂(如使用BIOS数据区的键盘缓冲区)
mov ah, 0eh ; 调用BIOS中断,在屏幕上显示字符(模拟输入效果)
int 10h
int_end:
pop ds
pop es
pop di
pop si
pop dx
pop cx
pop bx
pop ax ; 恢复寄存器状态
iret ; 中断返回
keyboard_int endp
; 扫描码到ASCII码的简化映射表(仅部分键,通码对应)
; 索引:扫描码(通码),值:ASCII码(0表示无对应)
scancode_to_ascii db 0 ; 00h(无键)
db 27 ; 01h(Esc,ASCII 27)
db '1' ; 02h(1键)
db '2' ; 03h(2键)
db '3' ; 04h(3键)
db '4' ; 05h(4键)
db '5' ; 06h(5键)
db '6' ; 07h(6键)
db '7' ; 08h(7键)
db '8' ; 09h(8键)
db '9' ; 0Ah(9键)
db '0' ; 0Bh(0键)
db '-' ; 0Ch(-键)
db '=' ; 0Dh(=键)
db 8 ; 0Eh(Backspace,ASCII 8)
db 9 ; 0Fh(Tab,ASCII 9)
db 'q' ; 10h(Q键)
db 'w' ; 11h(W键)
db 'e' ; 12h(E键)
db 'r' ; 13h(R键)
db 't' ; 14h(T键)
db 'y' ; 15h(Y键)
db 'u' ; 16h(U键)
db 'i' ; 17h(I键)
db 'o' ; 18h(O键)
db 'p' ; 19h(P键)
; 更多键的映射可继续添加...
; 安装中断向量(将自定义中断服务程序地址写入中断向量表)
install proc
cli ; 关中断,防止安装过程被打断
mov ax, 0
mov es, ax ; ES指向中断向量表段(0段)
mov di, 9*4 ; int 9h的向量地址:9*4=36(0000:0024)
mov ax, offset keyboard_int ; 中断服务程序偏移地址
stosw ; 写入偏移量到向量表
mov ax, cs ; 中断服务程序段地址(当前代码段)
stosw ; 写入段地址到向量表
sti ; 开中断
ret
install endp
; 主程序:安装中断后等待(实际使用中需保持程序运行以响应中断)
main:
call install ; 安装自定义int 9h中断
jmp $ ; 无限循环,等待中断
code ends
end main此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。