汇编语言:实验十三 编写、应用中断例程

第Ⅰ部分

1.编写并安装int 7ch中断例程,功能为显示一个用0结束的字符串,中断例程安装在 0:200处。
参数:(dh)= 行号,(dl)= 列号,(cl)= 颜色,ds:si指向字符串首地址。

Solution

第一部分实验与汇编语言:实验十二 编写0号中断的处理程序类似,这里就贴上代码吧:

assume cs:code, ds:data

code segment
start:
	jmp install
	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
	
install:
	mov ax, 0
	mov es, ax
	mov word ptr es:[4 * 7ch], 200h
	mov word ptr es:[4 * 7ch + 2], 0;安装中断向量表
	
	mov ax, cs
	mov ds, ax
	mov ax, 0
	mov es, ax
	mov si, 0
	mov di, 200h
	mov cx, offset do7chEnd - offset do7ch
	cld
	rep movsb
	
do7ch:
data segment
	db "welcome to masm!", 0
data ends

	push cx
	push si
	push di
	
	mov ax, 0b800h
	mov es, ax
	mov ax, data
	mov ds, ax
	mov si, 0;源地址偏移
	mov al, dh
	mov bl, 160
	mul bl	;dh * 160
	add ax, dl
	mov di, ax

trans:
	mov cl, [si]
	mov ch, 0
	jcxz fin;如果cx = 0,表示已经处理完毕
	mov byte ptr es:[di], cl
	mov byte ptr es:[di + 1], 11000010B
	inc si
	add di, 2
	jmp trans

fin:
	pop di
	pop si
	pop cx
	iret
	
do7chEnd:
	nop
code ends
end start

需要注意的还是在 data segment 的放置,如果直接放在主程序中会出现意想不到的错误哦,必须将其放在子程序中。

运行效果:
在这里插入图片描述

第Ⅱ部分

编写并安装 int 7ch 中断例程,功能为完成 loop 指令的功能。
参数:(cx)= 循环次数,(bx)= 位移。
在这里插入图片描述

Solution

程序总体涉及到多个部分,不过大体上跟之前一样,只是在中断处理程序上有不一样的处理方式。

install子程序

先看中断子程序是如何被安装到指定位置的(为了方便观看,这里放上了Notepad++中的代码截图):
在这里插入图片描述

这段代码也不难,首先是保存相关寄存器,然后填写中断向量表,紧接着将中断处理程序的代码拷贝到指定地址,最后从栈中恢复寄存器的值。

do7ch中断处理程序

在这里插入图片描述
首先是保存bp寄存器(保护工作),int 7ch实现loop指令的功能,在循环的时候需要做如下操作:

  1. dec cx;循环计数变量减一
  2. 如果cx为0,那么不再循环,执行循环代码后面的程序
  3. 如果cx不为0,那么继续循环,CS:IP指向循环体开始部分。
    如何让程序跑回循环开始的位置呢?这里bx寄存器已经保存了循环体代码的长度,中断处理过程如下:
    在这里插入图片描述
    所以,栈中是保存了调用程序的位置(IP),那么怎么访问到IP呢,很简单,[sp + 2]即可,最上层为bp(我们自己压入的),然后就是IP,再下面是CS,因为bp的长度为2,所以往后偏移2字节即可获得IP的值。(栈的内容如下图)
    在这里插入图片描述
    完整程序:
assume cs:code

code segment
start:
	call install	;调用中断安装程序
	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
	
	
install:
	push ax
	push es
	push ds
	push si
	push di
	push cx
	
	mov ax, 0
	mov es, ax
	mov word ptr es:[4 * 7ch], 200h
	mov word ptr es:[4 * 7ch + 2], 0;填写中断向量表
	
	;将中断处理程序拷贝到指定地址
	mov ax, cs
	mov ds, ax
	mov ax, 0
	mov es, ax	;目的段地址 0
	mov si, offset do7ch;源偏移地址
	mov di, 200h;目的偏移地址
	mov cx, offset do7chEnd - offset do7ch;程序的长度
	cld
	rep movsb
	
	pop cx
	pop di
	pop si
	pop ds
	pop es
	pop ax
	ret
	
do7ch:;从栈中取出子程序的偏移地址
	push bp
	mov bp, sp
	dec cx
	jcxz fin	;如果cx已经为0了,那么不再进行跳转,顺序执行即可
	add [bp + 2], bx;修改IP指向使其指向s程序开始处
fin:
	pop bp
	iret
do7chEnd:
	nop
code ends
end start
运行结果

在这里插入图片描述
还差最后一道题,明天更新~

-------------------------------我是分割线 9.22更-----------------------------------

第Ⅲ部分

下面的程序,分别在屏幕的第2、4、6、8行显示4句英文诗,补全程序。
在这里插入图片描述
在这里插入图片描述

Solution

需要补充的地方并不多,首先要知道,这道题是为了让我们熟悉使用BIOS和DOS提供的中断例程编程。

int 10h中断例程是 BIOS 提供的中断例程。其中包含了多个和屏幕输出相关的子程序。这里使用int 10h中断例程的设置光标的功能来完成在屏幕上的定向输出。

mov ah, 2	;置光标
mov bh, 0	;0页
mov dh, 5	;dh中放行号
mov dl, 12	;dl中放列号
int 10h

(ah)= 2表示调用第 10h 号中断例程的2号子程序,功能为设置光标位置,可以提供光标所在的行号和页号作为参数。

第一处需要填的就是调用int 10h 中断例程需要指定的那些个参数:
在这里插入图片描述


int 21h中断例程是 DOS 提供的中断例程,其中包含了 DOS 提供给程序员在编程时调用的子程序。

在书中的13.7章节中使用了int 21h中断例程在光标位置显示字符串的功能:

ds:dx 指向字符串	;要显示的字符串需用"$"作为结束符
mov ah, 9	;功能号9,表示在光标位置显示字符串
int 21h

(ah)= 9 表示调用第21h号中断例程的9号子程序,功能为在光标位置显示字符串,可以提供要显示字符串的地址作为参数。

第二处同样是为调用中断例程而设定参数:(设置需要输出的字符串位置)
在这里插入图片描述

最后两个需要填写的位置:修改偏移地址,为下一次循环做准备。
在这里插入图片描述
完整程序

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	;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	;改变偏移地址 2byte
	loop ok
	
	mov ax, 4c00h
	int 21h
code ends
end start
运行效果

在这里插入图片描述

  • 2
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

nepu_bin

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值