子程序名称:show_str
功能:在屏幕的指定位置,用指定颜色,显示一个用0结尾的字符串
参数: dh = 行号(0~24) dl = 列号(0~79) cl = 颜色 ds:si :字符串的首地址
返回:字符串显示在屏幕上
show_str: push ax //先把子程序中用到的寄存器入栈,保存寄存器的值,避免寄存器冲突
push cx
push dx
push es
push si
push di
mov ax,0b800h //80x25彩色显示模式内存空间开始地址B8000H的段地址
mov es,ax
mov al,160 //一行80个字符,一个字符占1字节,颜色属性占1字节共2个字节,一行占80*2=160个字节
mul dh //dh是8位,所以是8位乘法,另一个乘数默认放在AL中。 dh表示行号,al表示一行占用字符的个数,dh*al得到从B8000H开始到dh行之间的字符个数。乘法结果存放在AX中。
add dl,dl //dl表示列号,得到第dh行从0列到dl列占用的字符个数。(一个字符占用2个字节,所以这儿dl*2)
mov dh,0
add ax,dx //ax存放dh行之前的字符个数,dx存放dh行dl列之前的字符个数。ax,dx相加后得到第dh行,dl列相对于80x25彩色显示模式内存空间开始地址B8000H的偏移地址
mov di,ax //相对于80x25彩色显示模式内存空间开始地址B8000H的偏移地址存放在di,es:[di]指向字符显示需要写入的地址
mov ah,cl //颜色属性存放在ah
print: mov cl,ds:[si] //把ds:[si]指向的字符数据ASCII码放到cl
mov ch,0
jcxz print_end //如果cx为0,表示cl为0,表示ds:[si]指向的数据为0,字符串显示完毕
mov al,cl //把ds:[si]指向的字符数据ASCII码放到al,此时ax高8位ah存放颜色属性,低8位al存放字符数据ASCII码
mov es:[di],ax //ax中低8字符的ASCII码数据写入es:[di],ax中高8位颜色属性写入es:[di+1],
inc si //ds:[si]指向下一个字符
add di,2 //es:[di]指向下一个字符需要写入的地址。因为一个字符占用2个字节,所以这儿加2
jmp print
print_end: pop di //恢复之前压栈的寄存器的值
pop si
pop es
pop dx
pop cx
pop ax
ret
应用举例: 在屏幕的8行3列,用绿色显示data字符串
assume cs:code
data segment
db 'welcome to masm!',0
data ends
code segment
start: mov dh,7 //第8行
mov dl,2 //第3行
mov cl,2 //颜色属性
mov ax,data
mov ds,ax
mov si,0
call show_str
mov ax,4c00h
int 21h
code ends
end start