汇编学习(十)8086汇编拾遗 (9)
8086 外中断
可屏蔽中断:
可屏蔽中断是CPU可以不响应的中断。CPU是否响应屏蔽中断,需要看标志寄存器IF的位置。当CPU检测到可屏蔽中断信息的时候如果IF = 1.则CPU在执行完成当前指令后响应中断,引发中断过程;如果IF = 0,则不响应。
如果在中断处理程序中需要处理可屏蔽中断,可以用指令将IF置1,8086CPU提供的设置IF指令如下:
sti : 设置IF = 1
cli: 设置IF = 0
不可屏蔽中断:
不可屏蔽中断是CPU必须响应的中断,当CPU监测到不可屏蔽中断信息的时候,则在执行完当前指令后,立即响应,禁止其它的可屏蔽中断。
键盘输入:
键盘的输入会被int 9中断例程所响应.
一个例子,循环显示a~z
assume cs:code stack segment db 128 dup(0) stack ends code segment start: mov ax,stack mov ss,ax mov sp,128 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,4c00h int 21h 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 code ends end start
循环打印子母’a’ ~ ‘z’ ,当输入ESC的时候字母变色
assume cs:code
stack segment ;设置栈段
db 128 dup(0)
stack ends
data segment
dw 0,0 ;设置数据段
data ends
code segment
start:
mov ax,stack ;设置ss:sp
mov ss,ax
mov sp,128
mov ax,data ;设置ds ,ds 将会保存原int 9 的中断地址
mov ds,ax
mov ax,0 ;保存原来的int 9 地址
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 ;设置新的中断向量地址
mov word ptr es:[9*4+2],cs
mov ax,0b800h
mov es,ax
mov ah,'a'
S:mov es:[160*12+40*2],ah ;循环显示'a'~'z'
call delay
inc ah
cmp ah,'z'
jna s
mov ax,0
mov es,ax
push ds:[0] ;程序将要结束,恢复int9
pop es:[9*4]
push ds:[2]
pop es:[9*4+2]
mov ax,4c00h
int 21h
delay:
push ax ;设置CPU空转时间
push dx
mov dx,10h ;空转指令数10 * 10000H
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 ;标志进入bx
and bh,11111100b ;将标志设置IF = 0 ,TF = 0
push bx ;入栈当前设置标志
popf ;使用当前标志
call dword ptr ds:[0] ;调用原来的中断
cmp al,1 ;比较al是不是ESC扫描码
jne int9ret
mov ax,0b800h
mov es,ax
inc byte ptr es:[160*12+40*2+1]
int9ret:
pop es
pop bx
pop ax
iret
code ends
end start
新的中断程序,按F1就可以全屏变色
assume cs:code
stack segment
db 128 dup(0)
stack ends
code segment
start:
mov ax,stack
mov ss,ax
mov sp,128
push cs
pop ds
mov ax,0
mov es,ax
mov si,offset int9
mov di,204h
mov cx,offset int9end - offset int9
cld
rep movsb
push es:[9*4]
pop es:[200h]
push es:[9*4+2]
pop es:[202h]
cli
mov word ptr es:[9*4],204h
mov word ptr es:[9*4+2],0
sti
mov ax,4c00h
int 21h
int9:
push ax
push bx
push cx
push es
in al,60h
pushf
call dword ptr cs:[200h]
cmp al,3bh
jne int9ret
mov ax,0b800h
mov es,ax
mov bx,1
mov cx,2000
s:
inc byte ptr es:[bx]
add bx,2
loop s
int9ret:pop es
pop cx
pop bx
pop ax
iret
int9end:nop
code ends
end start
按下A 键松开后打印全屏的A
assume cs:code
code segment
start:
mov ax,cs
mov ds,ax
mov ax,0
mov es,ax
mov si,offset int9
mov di,204h
mov cx,offset int9end - offset int9
cld
rep movsb
push es:[9*4]
pop es:[200h]
push es:[9*4+2]
pop es:[202h]
cli
mov word ptr es:[9*4],204h
mov word ptr es:[9*4+2],0
sti
mov ax,4c00h
int 21h
int9:
push ax
push cx
push es
push di
in al,60h
pushf
call dword ptr cs:[200h]
cmp al,1EH+80H
jne int9ret
mov ax,0b800h
mov es,ax
mov di,0
mov cx,80*20
s: mov byte ptr es:[di],'A'
add di,2
loop s
int9ret:pop di
pop es
pop cx
pop ax
iret
int9end:nop
code ends
end start
查看原文:http://zmrlinux.com/2016/06/01/%e6%b1%87%e7%bc%96%e5%ad%a6%e4%b9%a0%ef%bc%88%e5%8d%81%ef%bc%898086%e6%b1%87%e7%bc%96%e6%8b%be%e9%81%97-9/
还没有评论,来说两句吧...