首页 > 代码库 > 外中断(学习汇编)

外中断(学习汇编)

外中断是指那些不再CPU内部产生的中断,即通过端口与cpu通信的外设产生的中断。

  1. 可屏蔽中断是CPU可以不响应的外中断
  2. 不可屏蔽中断是CPU必须响应的中断,其中断类型码都是2
  3. sti,cli可以屏蔽中断,让一些如改变中断向量的操作安全进行。

1. 可屏蔽中断,CPU根据标志寄存器IF位决定是否响应中断,IF=1,响应中断,IF=0,不响应中断。

  sti,用于设置IF=1;

      cli,用于设置IF=0。

2. 不可屏蔽中断,CPU必须响应中断。不可屏蔽中断的中断类型码固定为2,所以中断过程中,不需要取中断类型码。则不可屏蔽中断的中断过程为:

    (1)标志寄存器入栈,IF=0,TF=0;

    (2)CS、IP入栈;

    (3)(IP)=(8),(CS)=(0AH)。

 

 

程序1:在屏幕中某个位置一次输出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
mov ss,ax
mov sp,128

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
mov es:[9*4+2],cs

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

push ds:[0]
pop es:[9*4]
push ds:[2]
pop es:[9*4+2]

mov ax,4c00h
int 21h

delay:
push ax
push dx
mov dx,10h
mov ax,0

s1:
sub ax,1 ;sbb带借位减法指令0-1=ffff,CF=1
sbb dx,0 ;(dx)=(dx)-0-CF
cmp ax,0 ;相当于ffff*1000次
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
call dword ptr ds:[0]

cmp al,1
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

 

程序2:按f1改变屏幕显示颜色。

;cs总在高地址处
assume cs : codesg, ss : stacksg

stacksg segment
dw 64 dup (0)
stacksg ends

 

codesg segment

start: mov ax, stacksg
mov ss, ax
mov sp, 128
mov ax, 0
mov es, ax
mov ax, codesg
mov ds, ax
mov si, offset int9s
mov di, 0200h

cli
mov bx, offset table
mov ax, es : [9 * 4]
mov [bx], ax
mov ax, es : [9 * 4 + 2]
mov [bx + 2], ax
mov word ptr es : [9 * 4], 0200h
mov word ptr es : [9 * 4 + 2], 0
sti

mov cx, offset int9end - offset int9s
cld
rep movsb

mov ax, 4c00h
int 21h

int9s: jmp short sss
table dw 0, 0
sss: push ds
push ax
push cx
push si
pushf
mov ax, 0
mov ds, ax
call dword ptr ds : [202h]
in al, 60h
cmp al, 3bh
jne int9ret
mov si, 0
mov cx, 2000
mov ax, 0b800h
mov ds, ax
s1: inc byte ptr [si + 1]
add si, 2
loop s1
int9ret: pop si
pop cx
pop ax
pop ds
iret

int9end: nop
codesg ends
end start

 

程序3:在DOS下,按下‘A‘键后,松开就显示满屏幕‘A’。

;中断时的入栈顺序是pushf,push cs, push ip
assume cs : codesg, ss : stacksg

stacksg segment
dw 64 dup (0)
stacksg ends

 

codesg segment

start: mov ax, stacksg
mov ss, ax
mov sp, 128
mov ax, 0
mov es, ax
mov di, 0200h
mov si, offset int9
push cs
pop ds

cli
mov bx, offset table
mov ax, es : [9 * 4]
mov ds : [bx], ax
mov ax, es : [9 * 4 + 2]
mov ds : [bx + 2], ax
sti

mov cx, offset int9end - offset int9
cld
rep movsb

mov word ptr es : [9 * 4 + 2], 0
mov word ptr es : [9 * 4], 0200h

mov ax, 4c00h
int 21h

int9: jmp short s
table dw 0, 0
s: push ax
push cx
push si
push es
mov ax, 0
mov ds, ax
pushf
call dword ptr ds : [202h]
in al, 60h
cmp al, 9eh
jne int9ret
mov ax, 0b800h
mov es, ax
mov si, 0
mov cx, 2000
s1: mov byte ptr es : [si], ‘A‘
add si, 2
loop s1

int9ret:pop es
pop si
pop cx
pop ax
iret

int9end:nop
codesg ends
end start