在系统板的 ROM 中存放着一套程序,称为 BIOS(基本输入输出系统),BIOS 中主要包含以下几部分内容:
操作系统 DOS 也提供了中断例程,即向程序员提供的编程资源。
int 10h 是 BIOS 提供的中断例程,其中包含了多个和屏幕输出相关的子程序。一般来说,供程序员调用的中断例程中包含多个子程序,中断例程内部通过传入参数决定调用哪个子程序。BIOS 和 DOS 提供的中断例程,都用 AH 来传递内部子程序的编号。
int 10h 中断例程设置光标位置的功能:
mov ah,2 ;置光标
mov bh,0 ;显示在显示缓冲区的第0页
mov dh,5 ;行号
mov dl,12 ;列号
int 10h ;调用10h中断例程
int 10h 中断例程在光标位置显示字符的功能:
mov ah,9 ;(ah)=9表示调用第10h中断的9号子程序,功能为在光标位置显示字符
mov al,'a' ;字符
mov bl,7 ;颜色属性
mov bh,0 ;显示在显示缓冲区的第0页
mov cx,3 ;字符重复次数
int 10h ;调用10h中断例程
如在屏幕的 5 行 12 列显示 3 个红底闪烁绿色的字符 a。
assume cs:code
code segment
start:
mov ah,2 ;置光标
mov bh,0 ;第0页
mov dh,5 ;行号
mov dl,12 ;列号
int 10h
mov ah,9 ;置光标
mov al,'a' ;字符
mov bl,11001010b ;属性
mov bh,0 ;第0页
mov cx,3 ;字符重复次数
int 10h
mov ax,4c00h
int 21h
code ends
end start
程序运行结果:
int 21h 中断例程中在光标显示字符串功能:
ds:dx 指向字符串 ;待显示字符串需用$作为结束符
mov ah,9 ;功能号为9,表示在光标位置显示字符串
int 21h
编写并安装 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 dh,10
mov dl,10
mov cl,2
mov ax,data
mov ds,ax ;寄存器DS指向data段
mov si,0
int 7ch
mov ax,4c00h
int 21h
code ends
end start
中断处理程序将字符串显式在屏幕,相关参数根据调用中断例程的程序决定,该部分代码可借助 实验 10:编写子程序 中的实验任务 1。结合 上文 中 int 7ch 中断程序的安装,得到整体代码为:
assume cs:code
code segment
start:
mov ax,0
mov es,ax
mov di,200h
mov ax,cs
mov ds,ax
mov si,offset show
mov cx,offset showend-offset show
cld
rep movsb
mov ax,0
mov es,ax
mov word ptr es:[7ch*4],200h
mov word ptr es:[7ch*4+2],0h
mov ax,4c00h
int 21h
show:
mov ax,0b800h
mov es,ax ;段寄存器ES指向显式段
mov al,160
mul dh ;行偏移
mov bx,ax ;防止AX被覆盖
mov al,2
mul dl ;列偏移
add bx,ax ;最终偏移
mov ah,cl ;前面使用CL表示字符颜色,入栈保护
mov ch,0
mov di,0 ;偏移取字符
s:
mov cl,ds:[si]
jcxz exit ;(cx)等于零时跳转至exit
mov es:[bx+di],cl ;写入字符
mov es:[bx+di+1],ah ;写入字符属性
inc si
add di,2
jmp short s
exit:
iret
showend:
nop
code ends
end start
安装结果如下:
调用结果如下:
编写安装 int 7ch 中断例程,功能为完成 loop 指令的功能,在屏幕中间显式 80 个 !。
参数:(cx)=循环次数,(bx)=位移。
见 上文 的预备知识部分。
下面的程序,分别在第 2、4、6、8 行显示四句英文诗,补全程序。
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,____ ;行号
mov dl,0 ;列号
mov ah,2 ;置光标
int 10h
mov dx,____ ;ds:dx指向字符串
mov ah,9 ;21h的9号功能
int 21h
________
________
loop ok
mov ax,4c00h
int 21h
code ends
end start
$
结尾;标号 s 存放上述四个标号的偏移地址;row 存放各英文诗的存放行号。mov dh,[si]
$
结尾:mov dx,[bx]
inc si
add bx,2
整体代码为:
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,[si] ;行号
mov dl,0 ;列号
mov ah,2 ;置光标
int 10h
mov dx,[bx] ;ds:dx指向字符串
mov ah,9 ;int 21h的9号功能
int 21h
inc si ;si偏移1个字节,定义为db
add bx,2 ;bx偏移2个字节,定义为dw
loop ok
mov ax,4c00h
int 21h
code ends
end start
程序运行结果如下:
基于 BIOS 和 DOS 提供的中断例程,可以快速实现某些功能,如本文将其用于在屏幕中间显示字符串,比先前字写手写显示程序更快和更方便。