欢迎扫码关注微信公众号
代码如下:
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101assume cs:code data segment dw 0, 0 data ends code segment start: mov bx, 0 mov es, bx mov ax, data mov ds, ax push es:[9*4] pop ds:[0] push es:[9*4+2] pop ds:[2] ;保存原来int9的地址 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:[12*160+40*2], ah call delay inc ah cmp ah, 'z' jna s ;在程序结束的时候恢复int9中断例程 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 dx push ax mov dx, 10h mov ax, 0 ;dx作高位,ax作低位,结合下面的循环,就会执行10000000h次 s1: sub ax, 1 sbb dx, 0 cmp ax, 0 jne s1 cmp dx, 0 jne s1 pop ax pop dx ret int9: push ax push bx push es in al, 60h ;模拟int9的调用 ;-------------------------------------------; pushf pushf pop bx and bh, 11111100b push bx popf call dword ptr ds:[0] cmp al, 1 ;ESC的扫描码是01h, ;因此,只需要看它的低位是不是1就知道接收到的是不是ESC键了 ;-------------------------------------------; jne int9ret mov ax, 0b800h mov es, ax inc byte ptr es:[12*160+40*2+1] int9ret:pop es pop bx pop ax iret code ends end start ; int指令的调用 ; 1、标志寄存器入栈: ; pushf ; 2、将TF、IF标志位置为0 ; TF和IF在标志寄存器的第8和第9位置(最低位是0) ; pushf ; pop ax ; and ah, 11111100b ; push ax ; popf ;将处理后的标志寄存器的值通过栈传回标志寄存器 ; 3、CS、IP入栈 ; 4、IP=n*4, CS=n*4+2 ; 3、上面的两部可以合为一个操作: ; call dword ptr ds:[0] ; 相当于: ; push CS ; push IP ; IP=(ds)*16+0 ; CS=(ds)*16+2
安装int9中断例程
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112assume cs:code code segment start: 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] ;将系统的中断例程暂存在0:200和0:202单元中 ;在设置中断向量表时屏蔽中断 cli mov word ptr es:[9*4], 204h mov word ptr es:[9*4+2], 0 ;将新的中断例程起始地址填入中断向量表 sti mov ax, 4c00h int 21h ; s: mov es:[12*160+40*2], ah ; call delay ; inc ah ; cmp ah, 'z' ; jna s ; ;在程序结束的时候恢复int9中断例程 ; mov ax, 0 ; mov es, ax ; cli ; push ds:[0] ; pop es:[9*4] ; push ds:[2] ; pop es:[9*4+2] ; sti ; mov ax, 4c00h ; int 21h ; delay: push dx ; push ax ; mov dx, 10h ; mov ax, 0 ;dx作高位,ax作低位,结合下面的循环,就会执行10000000h次 ; s1: sub ax, 1 ; sbb dx, 0 ; cmp ax, 0 ; jne s1 ; cmp dx, 0 ; jne s1 ; pop ax ; pop dx ; ret int9: push ax push bx push cx push es in al, 60h pushf ; pushf ; pop bx ; and bh, 11111100b ; push bx ; popf call dword ptr cs:[200h] ;这段代码执行时cs是0 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 ; int指令的调用 ; 1、标志寄存器入栈: ; pushf ; 2、将TF、IF标志位置为0 ; TF和IF在标志寄存器的第8和第9位置(最低位是0) ; pushf ; pop ax ; and ah, 11111100b ; push ax ; popf ;将处理后的标志寄存器的值通过栈传回标志寄存器 ; 3、CS、IP入栈 ; 4、IP=n*4, CS=n*4+2 ; 3、上面的两部可以合为一个操作: ; call dword ptr ds:[0] ; 相当于: ; push CS ; push IP ; IP=(ds)*16+0 ; CS=(ds)*16+2
实验15:
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116assume cs:code code segment start: 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] ;将系统的中断例程暂存在0:200和0:202单元中 ;在设置中断向量表时屏蔽中断 cli mov word ptr es:[9*4], 204h mov word ptr es:[9*4+2], 0 ;将新的中断例程起始地址填入中断向量表 sti mov ax, 4c00h int 21h ; s: mov es:[12*160+40*2], ah ; call delay ; inc ah ; cmp ah, 'z' ; jna s ; ;在程序结束的时候恢复int9中断例程 ; mov ax, 0 ; mov es, ax ; cli ; push ds:[0] ; pop es:[9*4] ; push ds:[2] ; pop es:[9*4+2] ; sti ; mov ax, 4c00h ; int 21h ; delay: push dx ; push ax ; mov dx, 10h ; mov ax, 0 ;dx作高位,ax作低位,结合下面的循环,就会执行10000000h次 ; s1: sub ax, 1 ; sbb dx, 0 ; cmp ax, 0 ; jne s1 ; cmp dx, 0 ; jne s1 ; pop ax ; pop dx ; ret int9: push ax push bx push cx push es in al, 60h pushf ; pushf ; pop bx ; and bh, 11111100b ; push bx ; popf call dword ptr cs:[200h] ;这段代码执行时cs是0 cmp al, 9eh ;只要检测到A的断码,就持续输出A,指导屏幕满掉 jne int9ret mov ax, 0b800h mov es, ax mov bx, 0 mov cx, 2000 ;一个屏幕80*25 4000byte,每次增2,只需循环2000次 mov ah, 255 s: mov al, 'A' mov byte ptr es:[bx], al mov byte ptr es:[bx+1], ah dec ah ;每显示一个字符,就改变一次颜色 add bx, 2 loop s int9ret:pop es pop cx pop bx pop ax iret int9end:nop code ends end start ; int指令的调用 ; 1、标志寄存器入栈: ; pushf ; 2、将TF、IF标志位置为0 ; TF和IF在标志寄存器的第8和第9位置(最低位是0) ; pushf ; pop ax ; and ah, 11111100b ; push ax ; popf ;将处理后的标志寄存器的值通过栈传回标志寄存器 ; 3、CS、IP入栈 ; 4、IP=n*4, CS=n*4+2 ; 3、上面的两部可以合为一个操作: ; call dword ptr ds:[0] ; 相当于: ; push CS ; push IP ; IP=(ds)*16+0 ; CS=(ds)*16+2
实验结果:
最后
以上就是和谐煎蛋最近收集整理的关于王爽《汇编语言》第三版 编写INT9中断例程的全部内容,更多相关王爽《汇编语言》第三版内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复