实验十三
题目预览
- 编写并安装int 7ch中断例程,功能为显示一个用0结束的字符串,中断例程安装在0:200处。
- 编写并安装int 7ch中断例程,功能为完成loop指令的功能。
- 下面的程序,分别在屏幕的第2、4、6、8行显示4句英文诗,补全程序。
1
问题:
编写程序并安装int 7ch中断例程,功能为显示一个用0结束的字符串,中断例程安装在0:200处。
参数:(dh)=行号,(dl)=列号,(cl)=颜色,ds:si指向字符串首地址。
以上中断例程安装完成后,对下面的程序进行单步跟踪,尤其注意观察int、iret指令执行前后CS、IP和栈中的状态。
assume cs:code
data segment
db "welcome to masm! ",0
data ends
code segment
start:
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
int 7ch中断例程代码如下:
assume cs:code
code segment
start:
mov ax,cs
mov ds,ax
mov si,offset do7c
mov ax,0
mov es,ax
mov di,200h ;设置es:di指向目的地址
mov cx,offset do7cend-offset do7c ;设置cx为传输长度
cld ;设置传输方向为正
rep movsb
;设置中断向量表
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
do7c:
push ax
push es
push di
push bx
push cx
push si
mov ax,0b800h
mov es,ax
sub di,di
;计算显示位置
mov ax,160
mul dh
add di,ax
mov ax,2
mul dl
add di,ax
mov bl,cl ;后面要用到cl,放入bl中
do7c_show:
mov cl,ds:[si]
mov ch,0
jcxz ok
mov es:[di],cl
mov es:[di+1],bl ;高位属性,颜色
add di,2
inc si
jmp short do7c_show
ok:
pop si
pop cx
pop bx
pop di
pop es
pop ax
iret
do7cend:nop
code ends
end start
运行上面编写的中断例程再运行题目给的程序。
debug模式运行看细节。
int 7ch引发中断过程后,进入7ch中断例程,在中断过程中,当前的标志寄存器、CS和IP都要压栈此时压入的CS和IP中的内容,分别是调用程序的段地址(可以认为是标号s的段地址)和int 7ch后一条指令的偏移地址(即标号se的偏移地址)。
执行过程如下。
- 取中断类型码7cH。
- 标志寄存器入栈,IF=0,TF=0。
- CS、IP入栈。
- (IP)=(7cH*4),(CS)=(7cH*4+2)。
段地址存放在7cH*4+2=01F2字单元中,偏移地址存放在7cH*4=01F0字单元中。
本题中的CS:IP即指向0000:0200。即我们上面安装的7ch中断例程的程序。
如下图:
运行int 7ch的变化
下面就是运行我们安装的程序。(略过)
运行iret指令的变化。
2
编写并安装int 7ch中断例程,功能为完成loop指令的功能
参数:(cx)=循环次数,(bx)=位移。
以上中断例程安装成功后,对下面的程序进行单步跟踪,尤其注意观察int、iret指令执行前后CS、IP和栈中的状态。
在屏幕中间显示80个"!"。
assume cs:code
code segment
start:
mov ax,0b800h
mov es,ax
mov di,160*12
mov bx,offset s-offset se ;设置从标号se到标号s的转移位移
mov cx,80
s:
mov byte ptr es:[di],'!'
add di,2
int 7ch ;如果(cx)≠0,转移到标号s处
se:
nop
mov ax,4c00h
int 21h
code ends
end start
int 7ch中断例程代码如下:
assume cs:code
code segment
start:
mov ax,cs
mov ds,ax
mov si,offset lp
mov ax,0
mov es,ax
mov di,200h
mov cx,offset lpred-offset lp
cld
rep movsb
;设置中断向量表
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
lp:
push bp
mov bp,sp
dec cx
jcxz lpret
add [bp+2],bx
lpret:
pop bp
iret
lpred:
nop
code ends
end start
运行上面编写的中断例程再运行题目给的程序。
debug模式运行看int、iret指令执行前后CS、IP和栈中的状态。
下面就是运行我们安装的程序,即loop指令的功能。(略过)
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
strat:
mov ax,cs
mov ds,ax
mov bx,offset s
mov si,offset row
mov cx,4
ok:
mov bh,0
mov dh,______
mov dl,0
mov ah,2
int 10h
mov dx,______
mov ah,9
int 21h
______
______
loop ok
mov ax,4c00h
int 21h
code ends
end strat
程序如下:
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
strat:
mov ax,cs
mov ds,ax
mov bx,offset s
mov si,offset row
mov cx,4
ok:
mov bh,0
mov dh,ds:[si]
mov dl,0
mov ah,2
int 10h
mov dx,ds:[bx]
mov ah,9
int 21h
inc si
add bx,2
loop ok
mov ax,4c00h
int 21h
code ends
end strat
运行结果如下: