;====================================================================
;子程序SHOW_STR功能;在指定的位置,用指定的颜色,显示一个用0结尾的字符串。
;====================================================================
ASSUME CS:CODE,DS:DATA
DATA SEGMENT
DB 'Welcome to masm!',0
DATA ENDS
CODE SEGMENT
START:
MOV DH,8 ;(DH)=行号(0~24)
MOV DL,3 ;(DL)=列号(0~79)
MOV CL,2 ;(CL)=颜色
MOV AX,DATA ;初始化DS
MOV DS,AX
MOV SI,0 ;初始化SI,DS:SI指向字符串的首地址
CALL SHOW_STR ;调用子程序
MOV AX,4C00H
INT 21H
;-----------------------------------------------------------------------
;功能:在指定的位置,用指定的颜色,显示一个用0结尾的字符串。
;参数:(DH)=行号(0~24),(DL)=列号(0~79),(CL)=颜色,DS:SI指向字符串的首地址。
;返回:无
SHOW_STR:
PUSH AX ;保护现场
PUSH ES
PUSH DX
PUSH DI
PUSH SI
MOV AX,0B800H ;显示缓冲区段地址
MOV ES,AX ;(ES)=显示缓冲区段地址
MOV AL,0A0H ;以下计算初始字符的偏移地址
MUL DH ;行数×0A0H(160个字节)
MOV DI,AX ;转移到DI中
MOV AL,2 ;显示缓冲区中一个字符占两个字节空间
MUL DL ;2×列号
ADD DI,AX ;获得初始字符的偏移地址
S:
MOV AX,DS:[SI] ;输出字符到显示缓冲区
MOV ES:[DI],AX
INC DI ;准备写入颜色信息
MOV ES:[DI],CL ;写入颜色信息
INC SI ;准备输出下一个字符
PUSH CX ;保存颜色=(CL)
MOV CX,DS:[SI] ;(CX)=下一个字符
MOV CH,0 ;!!!若DS:[SI]的低位字节为零,但其高位字节不为零,
;!!!则程序不能如期望的那样跳转到END_SHOW
JCXZ END_SHOW ;不为零则继续输出,为零则结束子程序
POP CX ;恢复颜色=(CL)
INC DI ;准备写入下一个字符
JMP S ;输出下一个字符
END_SHOW:
POP CX ;!!!如果(CX)≠0,就会跳转到这里,此时(CX)在栈中还没有弹出
;!!!如果不弹出就会引发错误
POP SI ;恢复现场
POP DI
POP DX
POP ES
POP AX
RET
;------------------------------------------------------------------------
CODE ENDS
END START