实验13:编写、应用中断例程
1. 编写并安将int 7ch中断例程,功能为显示一个用0结束的字符串,中断例程安将在0:200处。
可以分为以下几个步骤进行:
- 将中断例程写入内存0:200中
- 设置中断向量表
- 写相关程序来测试(已经在上面给出,在此放在一起)
assume cs:code
code segment
start:
mov ax, 0
mov es, ax
mov di, 200h
mov ax, cs
mov ds, ax
mov si, offset interr
mov cx, offset endi - offset interr
cld
rep movsb ;安装到内存0:200
mov word ptr es:[7ch*4], 200h
mov word ptr es:[7ch*4+2], 0 ;写入向量表
mov ax, 4c00h
int 21h
interr:
mov ax, 0b800h
mov es, ax
mov bl, cl
mov al, 160
mul dh
mov dh, 0
add ax, dx
add ax, dx
mov di, ax
s:
mov cl, [si]
mov ch, 0
jcxz ok
mov byte ptr es:[di], cl
inc di
mov byte ptr es:[di], bl
inc di
inc si
jmp short s
ok:
iret
endi:
nop
code ends
end start
测试程序
assume cs:code
data segment
db "Welcome to masm!", 0
data ends
code segment
start:
;测试程序,10行,10列,颜色属性2
mov dh, 10
mov dl, 10
mov cl, 2
mov ax, data
mov ds, ax
mov si, 0
int 7ch
mov ax, 4c00h
int 21h
code ends
end start
下面改一下测试程序,让它输出多行,且每行不同颜色。因为cx要用于循环,所以上例的cl颜色在下例中用bl来替代,(两个放在同一个文件中运行)
assume cs:code
data segment
db "Welcome to masm! Talk is cheap, show me the code!", 0
data ends
code segment
start:
mov ax, 0
mov es, ax
mov di, 200h
mov ax, cs
mov ds, ax
mov si, offset interr
mov cx, offset endi - offset interr
cld
rep movsb ;安装到内存0:200
mov word ptr es:[7ch*4], 200h
mov word ptr es:[7ch*4+2], 0 ;写向量表
mov dh, 0
mov dl, 10
mov bl, 1 ;颜色从1开始
mov ax, data
mov ds, ax
mov si, 0
mov cx, 25 ;输出25行
output:
int 7ch
inc dh
inc bl ;变化一次
loop output
mov ax, 4c00h
int 21h
interr:
push cx
push dx
push ax
push si
mov ax, 0b800h
mov es, ax
mov al, 160
mul dh
mov dh, 0
add ax, dx
add ax, dx
mov di, ax
s:
mov cl, [si]
mov ch, 0
jcxz ok
mov byte ptr es:[di], cl
inc di
mov byte ptr es:[di], bl
inc di
inc si
jmp short s
ok:
pop si
pop ax
pop dx
pop cx
iret ;跳回
endi:
nop
code ends
end start
2. 编写并安装int 7ch中断例程,功能为完成loop指令的功能
assume cs:code
code segment
start:
mov ax, 0
mov es, ax
mov di, 200h
mov ax, cs
mov ds, ax
mov si, offset lp
mov cx, offset e - offset lp
cld
rep movsb ;写入内存0:200h
mov ax, 0
mov es, ax
mov word ptr es:[7ch*4], 200h
mov word ptr es:[7ch*4+2], 0 ;写入向量表
mov ax, 0b800h
mov es, ax
mov di, 160*12
mov bx, offset s - offset se
mov cx, 80
s: mov byte ptr es:[di], '!'
add di, 2
int 7ch
se: nop
mov ax, 4c00h
int 21h
;中断程序
lp: push bp ;bp入栈
mov bp, sp
dec cx ;cx减1
jcxz lpret
add [bp+2], bx ;将IP加上转移的位移量
lpret: pop bp
iret
e: nop
code ends
end start
执行完int 7ch后TF、CS、IP先后压栈,再压一个bp,堆栈指针sp指向bp,IP就是bp+2。循环就是要改变IP。所以:
add [bp+2], bx ;将IP加上转移的位移量
当然这个程序bp不入栈也可以,bp没入栈那就不用+2了。所以,将中断程序改成下面的也行
lp:
mov bp, sp
dec cx
jcxz lpret
add [bp], bx
lpret:
iret
3. 下面的程序,分别在屏幕的第2、4、6、8行显示4句英文诗,补全程序。
assume cs:code
code segment
s1: db 'Good, better, best,','$'
s2: db 'Never let it rest,','$'
s3: db 'Till good is better,','$'
s4: db 'And better, best.','$'
s : dw offset s1, offset s2, offset s3, offset s4
row: db 2, 4, 6, 8
start: mov ax, cs
mov ds, ax
mov bx, offset s
mov si, offset row
mov cx, 4
ok: mov bh, 0
mov dh, [si]
mov dl, 0
mov ah, 2
int 10h
mov dx, [bx]
mov ah, 9
int 21h
inc si
add bx, 2
loop ok
mov ax, 4c00h
int 21h
code ends
end start