外中断(学习汇编)
外中断是指那些不再CPU内部产生的中断,即通过端口与cpu通信的外设产生的中断。
- 可屏蔽中断是CPU可以不响应的外中断
- 不可屏蔽中断是CPU必须响应的中断,其中断类型码都是2
- 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
 
                    
                     
                    
                 
                    
                 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号