实验13
实验 13 编写、应用中断例程
编写并安装 int 7ch 中断例程,功能为显示一个用 0 结束的字符串, 中断例程安装在 0:200 处。 参数:(dh)=行号,(dl)=列号,(cl)=颜色,ds:si 指向字符串首地址。
assume cs:code
data segment
db 'welcome to masm!',0
data ends
code segment
start:
mov ax,cs
mov ds,ax
mov si,offset dp ; 0038
mov ax,0
mov es,ax
mov di,200h
mov cx,offset dpend - offset dp ; 安装中断例程
cld
rep movsb
; -u 0e26:0038
; 0E26:0038 B0A0 MOV AL,A0
; 0E26:003A F6E6 MUL DH
; 0E26:003C 02D2 ADD DL,DL
; 0E26:003E B600 MOV DH,00
; 0E26:0040 03C2 ADD AX,DX
; 0E26:0042 8BF8 MOV DI,AX
; 0E26:0044 B800B8 MOV AX,B800
; 0E26:0047 8EC0 MOV ES,AX
; -d es:200
; 0000:0200 B0 A0 F6 E6 02 D2 B6 00-03 C2 8B F8 B8 00 B8 8E ................
; 0000:0210 C0 8A 04 B4 00 83 F8 00-74 0A 8A E1 26 89 05 46 ........t...&..F
; 0000:0220 47 47 EB ED CF 00 00 00-00 00 00 00 00 00 00 00 GG..............
mov word ptr es:[7ch*4],200h
mov word ptr es:[7ch*4+2],0 ; 设置中断向量表
; -d es:01F0
; 0000:01F0 00 02 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
mov dh,10 ; 行号
mov dl,10 ; 列号
mov cl,2 ; 颜色
mov ax,data
mov ds,ax ; 测试 int 7ch
mov si,0
int 7ch
mov ax,4c00h
int 21h
dp:
mov al,160
mul dh
add dl,dl
mov dh,0
add ax,dx
mov di,ax
mov ax,0b800h
mov es,ax
;中断例程
s:
mov al,ds:[si]
; -d ds:0
; 0E24:0000 77 65 6C 63 6F 6D 65 20-74 6F 20 6D 61 73 6D 21 welcome to masm!
mov ah,0
cmp ax,0
je f
mov ah,cl
mov es:[di],ax
inc si
inc di
inc di
jmp s
f:
iret
dpend:
nop
code ends
end start
实验 13 编写并安装 int 7ch 中断例程,功能为完成 loop 指令的功能
参数:(cx)=循环次数,(bx)=位移
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 lpend-offset lp ; 安装中断例程
cld
rep movsb
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],'!' ; 测试 int 7ch
add di,2
int 7ch
se:
nop
mov ax,4c00h
int 21h
lp:
push bp
dec cx
jcxz f
mov bp,sp
add [bp+2],bx ; 中断例程
f:
pop bp
iret
lpend:
nop
code ends
end start
实验 13 下面的程序,分别在屏幕的第 2、4、6、8 行显示四句英文诗,补全程序
assume cs:code
code segment
; 数据定义
s1: db 'Good,better,best,','#x27; ; 定义字符串s1,以'#x27;字符结束
s2: db 'Never let it rest,','#x27; ; 定义字符串s2,以'#x27;字符结束
s3: db 'Till good is better,','#x27; ; 定义字符串s3,以'#x27;字符结束
s4: db 'And better,best.','#x27; ; 定义字符串s4,以'#x27;字符结束
s: dw offset s1,offset s2,offset s3,offset s4 ; 定义字符串偏移量数组s
row: db 2,4,6,8 ; 定义字符串应该被显示的行数
; 程序入口点
start:
mov ax,cs ; 将代码段地址复制到AX寄存器
mov ds,ax ; 将AX寄存器的值赋给DS,设置数据段指针
mov bx,offset s ; 将字符串偏移量数组的地址加载到BX寄存器
mov si,offset row ; 将显示行数数组的地址加载到SI寄存器
mov cx,4 ; 设置循环次数为4(因为有4个字符串)
ok: mov bh,0 ; 页面号设置为0,用于显示功能
mov dh,ds:[si] ; 读取要显示字符串的行号
mov dl,0 ; 列号设置为0(屏幕最左边)
mov ah,2 ; 设置功能号为2,准备调用设置光标位置的BIOS中断
int 10h ; 调用BIOS中断10h,它处理屏幕显示相关功能
mov dx,ds:[bx] ; 从字符串偏移量数组中获取当前字符串的偏移量
mov ah,9 ; 设置DOS功能号为9,准备调用显示字符串的DOS中断
int 21h ; 调用DOS中断21h,它处理多种操作系统级功能
inc si ; 移动到下一个行号
add bx,2 ; 移动到下一个字符串偏移量(偏移量是2字节)
loop ok ; 循环直到CX为0
mov ax,4c00h ; 设置DOS退出功能码和退出代码(00h)
int 21h ; 调用DOS中断21h来退出程序
code ends
end start
; 程序的工作流程如下:
; 首先,程序将代码段寄存器(CS)的地址赋值给数据段寄存器(DS),以便于访问数据。
; 然后,程序初始化了两个指针,BX指向字符串偏移量数组s,SI指向行数数组row。
; 接着程序进入一个循环,每次循环显示一个字符串。
; 在循环内部,首先使用BIOS中断10h(AH=2)设置光标位置到指定的行(从row数组中读取)和列(这里始终设为0)。
; 然后使用DOS中断21h(AH=9)显示字符串(字符串地址通过s数组和BX寄存器获得)。
; 循环四次后,所有字符串都显示在屏幕上。
; 最后,程序通过DOS中断21h(AH=4Ch)退出。