0%

汇编:实验16:安装新的7ch中断例程

中断例程装载程序源码:

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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
; 安装新的 7ch 中断例程,实现如下功能的子程序:
; 1) 清屏
; 2) 设置前景色
; 3) 设置背景色
; 4) 向上滚动一行

; 入口参数:
; ah=功能号:0清屏,1前景色,2背景色,3向上滚动一行
; 对于1、2号功能,用al传递颜色值,范围0~7的整数

assume cs:code
code segment
start:
mov ax,cs
mov ds,ax
mov si,offset setscreent ; ds:si指向中断例程的代码

mov ax,0
mov es,ax
mov di,200h ; es:di指向中断例程装载位置
mov cx,offset setsrcend - offset setscreent ; 中断例程长度
cld
rep movsb ; 串传输

; 设置 7ch 号中断向量
mov ax,0
mov es,ax
mov word ptr es:[7ch*4],200h
mov word ptr es:[7ch*4+2],0

mov ax,4c00h
int 21h

; 中断处理程序开始
setscreent:
jmp short set ; 此指令占2字节
; 此dw数据开始地址为 0:200h入口地址+2 即0:202h
; sub1为数据标号,dw sub1相当于dw offset sub1
dw 200h+sub1-setscreent,200h+sub2-setscreent,200h+sub3-setscreent,200h+sub4-setscreent
set:
push bx
cmp ah,3 ; 判断功能号是否大于3
ja sret
mov bl,ah
mov bh,0
add bx,bx ; ah中的功能号*2=table表中的偏移
call word ptr cs:[bx+202h] ; 此中断执行时,cs=0
sret:
pop bx
iret

sub1: ; 清屏
push bx
push cx
push es
mov bx,0b800h
mov es,bx
mov bx,0 ; 显存的偶地址单元为字符
mov cx,2000
sub1s:
mov byte ptr es:[bx],' ' ; 空格填充屏幕
add bx,2
loop sub1s
pop es
pop cx
pop bx
ret

sub2: ; 设置字体颜色
push bx
push cx
push es
mov bx,0b800h
mov es,bx
mov bx,1 ; 显存的奇地址单元为属性
mov cx,2000
sub2s:
and byte ptr es:[bx],11111000b
or es:[bx],al
add bx,2
loop sub2s
pop es
pop cx
pop bx
ret

sub3: ; 设置背景色
push bx
push cx
push es
mov cl,4
shl al,cl
mov bx,0b800h
mov es,bx
mov bx,1
mov cx,2000
sub3s:
and byte ptr es:[bx],10001111b
or es:[bx],al
add bx,2
loop sub3s
pop es
pop cx
pop bx
ret

sub4: ; 向上滚动一行
push cx
push si
push di
push es
push ds
mov si,0b800h
mov es,si
mov ds,si
mov si,160 ; ds:si指向n+1行
mov di,0 ; es:di指向n行
cld
mov cx,24 ; 共复制24行
sub4s:
push cx
mov cx,160
rep movsb ; 一行复制完,si+=160,di+=160
pop cx
loop sub4s
mov cx,80
mov si,0
sub4s1:
mov byte ptr [160*24+si],' ' ; 最后一行清空
add si,2
loop sub4s1
pop ds
pop es
pop di
pop si
pop cx
ret
; 中断处理程序结束

setsrcend:
nop

code ends
end start

测试源码:

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
; 测试新的 7ch 中断例程

assume cs:code
code segment
; 测试清屏
mov ah,0
int 7ch

; 测试绿色字
mov ah,1
mov al,2
int 7ch

; 测试红底
mov ah,2
mov al,4
int 7ch

; 向上滚动一行
mov ah,3
int 7ch

mov ax,4c00h
int 21h
code ends
end

结果: