鸿 网 互 联 www.68idc.cn

8086汇编学习小记-王爽汇编语言第十五章外中断及实验15

来源:互联网 作者:佚名 时间:2015-09-03 08:12
外 中断 是指那些不再CPU内部产生的 中断 ,即通过端口与cpu通信的外设产生的 中断 。 可屏蔽 中断 是CPU可以不响应的外 中断 不可屏蔽 中断 是CPU必须响应的 中断 ,其 中断 类型码都是2 sti,cli可以屏蔽 中断 ,让一些如改变 中断 向量的操作安全进行。

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

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

(1)下面程序在屏幕中某个位置一次输出A~Z,按ESC改变该位置颜色:

 1 ;中断时的入栈顺序是pushf,push cs, push ip
 2 assume cs : codesg, ss : stacksg
 3 
 4 stacksg SEGMENT
 5      dw 64 dup (0)
 6 stacksg ENDS
 7 
 8 
 9 
10 codesg SEGMENT
11 
12 start:    ;改变中断向量到本程序中的中断例程处
13     mov ax, 0
14     mov es, ax
15     mov ax, stacksg
16     mov ss, ax
17     mov sp, 64
18     mov ds, ax
19     
20     ;分别将中断程序cs:ip入栈ds:[si]分别存ip,cs
21     push es : [9 * 4 + 2]
22     push es : [9 * 4]
23     mov si, sp
24     
25     ;改变中断向量
26     cli
27     mov ax, codesg
28     mov es : [9 * 4 + 2], ax
29     mov word ptr es : [9 * 4], offset int9
30     sti
31     
32     mov ax, 0b800h
33     mov es, ax
34     mov bl, 'A'
35 print:    mov es : [12 * 160 + 36 * 2], bl
36     add bl, 1
37     call delay
38     cmp bl, 'Z'
39     jna print
40     
41     ;改回中断向量
42     mov ax, 0
43     mov es, ax
44     cli
45     mov ax, word ptr ds : [si + 2]
46     mov es : [9 * 4 + 2], ax
47     mov ax, word ptr ds : [si]
48     mov es : [9 * 4], ax
49     sti
50 
51     mov ax, 4c00h
52     int 21h
53 
54 
55 delay:    push ax
56     push bx
57     mov ax, 0
58     mov bx, 1000h
59 wl:    sub ax, 1
60     sbb bx, 0
61     cmp ax, 0
62     jne wl
63     cmp bx, 0
64     jne wl
65     pop bx
66     pop ax
67     ret
68 
69 ;原来的中断例程存放在ds:[si]处
70 int9:        push ax
71         push es
72         pushf ;中断例程最后是iret
73                 ;注意是dword
74         call dword ptr ds : [si] ;运行原中断例程处理硬件细节
75 
76         in al, 60h
77         cmp al, 1
78         jne int9end
79 
80         mov ax, 0b800h
81         mov es, ax
82         add byte ptr es : [12 * 160 + 36 * 2 + 1], 1
83 
84 int9end:    pop es
85         pop ax
86         iret
87 codesg ENDS
88 END start
89     

在windows XP下运行有效果不过会导致鼠标左键失灵。

(2)安装新的int 9中断历程,按f1改变屏幕显示颜色:

 1 ;cs总在高地址处
 2 assume cs : codesg, ss : stacksg
 3 
 4 stacksg SEGMENT
 5      dw 64 dup (0)
 6 stacksg ENDS
 7 
 8 
 9 
10 codesg SEGMENT
11 
12 start:    mov ax, stacksg
13     mov ss, ax
14     mov sp, 128
15     mov ax, 0
16     mov es, ax
17     mov ax, codesg
18     mov ds, ax
19     mov si, offset int9s
20     mov di, 0200h
21     
22     cli
23     mov bx, offset table
24     mov ax, es : [9 * 4]
25     mov [bx], ax
26     mov ax, es : [9 * 4 + 2]
27     mov [bx + 2], ax
28     mov word ptr es : [9 * 4], 0200h
29     mov word ptr es : [9 * 4 + 2], 0
30     sti
31 
32     mov cx, offset int9end - offset int9s
33     cld
34     rep movsb
35 
36     mov ax, 4c00h
37     int 21h
38 
39 int9s:        jmp short sss
40         table dw 0, 0
41     sss:    push ds
42         push ax
43         push cx
44         push si
45         pushf
46         mov ax, 0
47         mov ds, ax
48         call dword ptr ds : [202h]
49         in al, 60h
50         cmp al, 3bh
51         jne int9ret
52         mov si, 0
53         mov cx, 2000
54         mov ax, 0b800h
55         mov ds, ax
56     s1:    inc byte ptr [si + 1]
57         add si, 2
58         loop s1
59 int9ret:    pop si
60         pop cx
61         pop ax
62         pop ds
63         iret
64 
65 int9end:    nop
66 codesg ENDS
67 END start

效果不错~

(3)安装新的int9中断例程,在DOS下,按下'A'键后,松开就显示满屏幕‘A’,其他照旧:

 1 ;中断时的入栈顺序是pushf,push cs, push ip
 2 assume cs : codesg, ss : stacksg
 3 
 4 stacksg SEGMENT
 5      dw 64 dup (0)
 6 stacksg ENDS
 7 
 8 
 9 
10 codesg SEGMENT
11 
12 start:    mov ax, stacksg
13     mov ss, ax
14     mov sp, 128
15     mov ax, 0
16     mov es, ax
17     mov di, 0200h
18     mov si, offset int9
19     push cs
20     pop ds
21     
22     cli
23     mov bx, offset table
24     mov ax, es : [9 * 4]
25     mov ds : [bx], ax
26     mov ax, es : [9 * 4 + 2]
27     mov ds : [bx + 2], ax
28     sti
29     
30     mov cx, offset int9end - offset int9
31     cld
32     rep movsb
33 
34     mov word ptr es : [9 * 4 + 2], 0
35     mov word ptr es : [9 * 4], 0200h
36     
37     mov ax, 4c00h
38     int 21h
39 
40 int9:    jmp short s
41     table dw 0, 0
42 s:    push ax
43     push cx
44     push si
45     push es
46     mov ax, 0
47     mov ds, ax
48     pushf
49     call dword ptr ds : [202h]
50     in al, 60h
51     cmp al, 9eh
52     jne int9ret
53     mov ax, 0b800h
54     mov es, ax
55     mov si, 0
56     mov cx, 2000
57 s1:    mov byte ptr es : [si], 'A'
58     add si, 2
59     loop s1
60 
61 int9ret:pop es
62     pop si
63     pop cx
64     pop ax
65     iret
66 
67 int9end:nop
68 codesg ENDS
69 END start

因为一个ds寄存器忘记保护现场,导致莫名其妙的错误,谨慎~

网友评论
<