中断:CPU不再接着刚执行完的指令向下执行,而是转去处理中断信息
内中断:由CPU内部发生的事件而引起的中断
如:除法错误,单步执行,执行into指令,执行int n指令
外中断:由外部设备发生的事件引起的中断
中断过程:
1)从中断信息中取得中断类型码N
2)pushf 标志寄存器的值入栈–中断过程中要改变标志寄存器的值,需要先行保护
3)设置标志寄存器的第八位TF和第九位IF的值为0–TF:陷阱标志,用于单步调试;IF:中断标志
4)push CS
5)push IP
6)从中断向量表读取中断处理程序的入口地址,设置IP,CS
端口读写:
in: CPU从端口读取数据
out: CPU往端口写入数据
eg:提取CMOS RAM中存储的时间信息,在屏幕的左上角能动态显示时间
该芯片内部有两个端口,端口地址为70h和71h,CPU 通过这两个端口读写CMOS RAM。
70h地址端口,存放要访问的CMOS RAM单元的地址;
71h数据端口,存放从选定的单元中读取的数据,或要写入到其中的数据。
读取CMOS RAM的两个步骤
1)将要读取的单元地址送入70h地址端口;
2)从数据端口71h读出指定单元的内容
当前时间在CMOS RAM中用6个字节存放
assume cs:code
code segment
start:mov al,2 ;分
out 70h,al
in al,71h ;具体数据读入到cpu
;分离十、个位
mov ah,al
mov cl,4
shr ah,cl
and al,00001111b
add ah,30h ;转换为ASCII码
add al,30h
mov bx,0b800h
mov es,bx
mov byte ptr es:[0],ah
mov byte ptr es:[1],01001111b
mov byte ptr es:[2],al
mov byte ptr es:[3],01001111b
mov byte ptr es:[4],':'
mov byte ptr es:[5],01001111b
mov al,0 ;秒
out 70h,al
in al,71h
mov ah,al
mov cl,4
shr ah,cl
and al,00001111b
add ah,30h
add al,30h
mov bx,0b800h
mov es,bx
mov byte ptr es:[6],ah
mov byte ptr es:[7],01001111b
mov byte ptr es:[8],al
mov byte ptr es:[9],01001111b
jmp start
mov ax,4c00h
int 21h
code ends
end start
PC机键盘的处理过程(int 9 中断例程)
eg:编写程序,模仿射击游戏中,用上、下、左、右键控制跳上、跳下、装子弹、射击的动作,ESC键退出游戏
assume cs:code, ss:stack, ds: data
stack segment
db 256 dup (0)
stack ends
data segment
dw 0,0
run db 'Game is runing...',0dh,0ah,'$'
up db 'Jump up...',0dh,0ah,'$'
down db 'Jump down...',0dh,0ah,'$'
right db 'shoot...',0dh,0ah,'$'
left db 'get bullet...',0dh,0ah,'$'
over db 'Byebye...',0dh,0ah,'$'
data ends
code segment
start:
;设置各段地址
mov ax,stack
mov ss,ax
mov sp,256
mov ax,data
mov ds,ax
mov ax,0
mov es,ax
;保存原中断例程入口地址
push es:[9*4]
pop ds:[0]
push es:[9*4+2]
pop ds:[2]
;改变后中断的入口地址
mov word ptr es:[9*4],offset int9 ;IP
mov word ptr es:[9*4+2],cs ;CS
;游戏进行中
op_run:lea dx,run
call show
call delay
jmp op_run
;延时程序
delay:push ax
push dx
mov dx,10h
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
;定义新的9号中断
;调用原int9指令的中断例程,模拟对原中断例程的调用
int9:push ax
push bx
push es
in al,60h
pushf ;标志寄存器入栈
;IF,TF置为0
pushf
pop bx
and bh,11111100b
push bx
popf
call dword ptr ds:[0] ;调用原来的int9中断例程,处理硬件细节
cmp al,1 ;esc
jne op_up
lea dx,over
call show
jmp finish
op_up: cmp al,72 ;up
jne op_down
lea dx,up
call show
op_down:cmp al,80 ;down
jne op_left
lea dx,down
call show
op_left:cmp al,75 ;left
jne op_right
lea dx,left
call show
op_right:cmp al,77 ;right
jne int9ret
lea dx,right
call show
int9ret:pop es
pop bx
pop ax
iret
int9_end:nop
;21号中断的九号功能:输出一个字符串
show:mov ah,09h
int 21h
ret
;恢复原来的int9中断并退出
finish:push ds:[0]
pop es:[9*4]
push ds:[2]
pop es:[9*4+2]
mov ax,4c00h
int 21h
code ends
end start