《汇编语言》第十五章主要通过拦截“BIOS键盘输入中断例程”(int 9)为例,介绍X86 CPU外部中断的机制和处理过程。本文将简述“外中断”的基本原理和给出所有习题的答案。
一、什么是外中断
1,CPU的第二项功能
CPU的第一项功能是“执行指令,进行运算”,除此之外,CPU的第二项功能就是“控制外部设备”,具体来说就是,CPU对外设的IO功能(Input/Output)。
为了简化,我们仅讲解Input功能。CPU要及时处理外设的输入,需要处理好以下两个问题:
1)外设的输入随时可能发生,CPU如何得知?
2)CPU从何处得到外设的输入?
2,外中断和端口
首先,我们来回答上面的两个问题。对于第一个问题,CPU设计者设计了外中断机制,实时感知当前是否有外设的输入。外中断和内中断类似,当中断发生时,CPU在执行完当前指令后,就会转去执行相应的中断例程,然后再返回中断发生前的地方继续原理的执行流程。
外中断与内中断不同的是:1)中断源不同;2)标志位不同。外中断产生后,会检测“IF”中断标志位(可屏蔽中断),内中断的单步调试中断,则检测“TF”中断标志位。
第二个问题的答案是,CPU通过端口和外部设备进行联系,即“外中断信息缓存在相应的端口中”。
二、键盘输入的处理过程
1,键盘输入
键盘上的每一个键相当于一个开关,键盘中有一个芯片会对各个键盘的开关状态进行扫描,产生扫描码,并发送到主板上相关的接口芯片的寄存器中,该寄存器的端口地址为60h。
按下和松开键盘,都会产生扫描码,前者称为通码(对应电路的通路),后者称为断码(对应断路)。两者有一个线性关系:断码 = 通码 + 80h
2,引发9号中断
键盘的输入到达60h端口时,相关的芯片就会向CPU发出中断类型码为9的可屏蔽中断信息。CPU检测到该中断信息后,如果IF=1,则响应中断,引发中断过程,转去执行int 9中断例程。
3,执行int 9中断例程
BIOS提供了int 9中断例程,如下:
1)读取60h端口中的扫描码;
2)发送扫描码和对应的字符ANSII码到内存的BIOS键盘缓存区或修改状态字(后者对应控制码)。
3)对键盘系统进行控制。
三、习题
检测点15.1
拦截int 9中断例程
assume cs:code
stack segment
db 128 dup(0)
stack ends
data segment
dw 0,0
data ends
code segment
start:mov ax,stack
mov ss,ax
mov sp,128
mov ax,data
mov ds,ax
mov ax,0
mov es,ax ; interrupt vector table
push es:[9*4]
pop ds:[0]
push es:[9*4+2]
pop ds:[2] ; save the orignal entry address
cli
mov word ptr es:[9*4],offset int9
mov es:[9*4+2],cs ; replace the entry address
sti
mov ax,0b800h
mov es,ax
mov ah,'a'
s:mov es:[160*12+40*2],ah
call delay
inc ah
cmp ah,'z'
jna s
mov ax,0
mov es,ax
cli
push ds:[0]
pop es:[9*4]
push ds:[2]
pop es:[9*4+2] ; recover IVT
sti
mov ax,4c00h
int 21h
delay:push ax
push dx
mov dx,1000h
mov ax,0
s1:sub ax,1
sbb dx,0
cmp ax,0
jne s1
cmp dx,0
jne s1
pop dx
pop ax
ret
int9:push ax
push bx
push es
in al,60h
pushf
;pushf
;pop bx
;and bh,11111100b
;push bx
;popf ; set IF=0,TF=0
call dword ptr ds:[0] ; call orignal int 9 routine
cmp al,1 ; esc - 01
jne int9ret
mov ax,0b800h
mov es,ax
inc byte ptr es:[160*12+40*2+1] ; change the propety value
int9ret:pop es
pop bx
pop ax
iret
code ends
end start