解:在文本显示方式下,每行显示80个字符,每个字符占2个字节,所以,显示一行需要160个字节。若在第m行、第n列位置显示字符,则该位置所对应存储单元的偏移量为:m×160 + n×2。
.MODEL SMALL .DATA Yellow EQU 0EH MSG1 DB "Welcome..." Count EQU $-MSG1 .CODE .STARTUP MOV AX, 0B800H MOV ES, AX ;彩色显示器的显示缓冲区段地址 MOV DI, 5 IMUL DI, 160 ;5行所跳过的显示存储单元 MOV CX, 10 SHL CX, 1 ;10列所跳过的显示存储单元 ADD DI, CX ;第5行、第10列之前所跳过的所有显示单元 MOV CX, Count LEA SI, MSG1 ;CX:字符个数,SI:显示字符首地址 MOV AH, Yellow ;设置显示属性,即显示颜色 .REPEAT LODSB ;取显示字符 STOSW ;向显示缓冲区设置显示字符和属性 .UNTILCXZ .EXIT 0 END
例8.3 用“霓虹灯”的显示方式显示字符串"Hello",按ESC键时结束程序的运行。
解:
.MODEL SMALL, C
.DATA
KBEsc EQU 1BH
BUFF DB "H", 15, "e", 15, "l", 15, "l", 15, "o", 15
.CODE
Clear PROC Near Uses AX BX CX DX ;清屏幕,并保护所用寄存器
MOV CL, 0
MOV CH, 0
MOV DL, 79
MOV DH, 24 ;(0,0)-(24,79)是屏幕的左上角和右下角
MOV BH, 7
MOV AL, 0
MOV AH, 6
INT 10H
RET
Clear ENDP
.STARTUP
CALL Clear
MOV AX, DS
MOV ES, AX
MOV SI, 9
again:
MOV BUFF[SI], 15 ;把前一次的红色还原
ADD SI, 2
.IF SI > 9
MOV SI, 1
.ENDIF
MOV BUFF[SI], 12 ;把当前字符以红色显示
MOV BH, 0
MOV CX, 5
MOV DH, 5
MOV DL, 20 ;显示位置从(5, 20)开始
LEA BP, BUFF
MOV AL, 2
MOV AH, 13H
INT 10H ;调用中断10H之功能13H
MOV AH, 1
INT 16H ;检查是否有按键
JZ again ;若无字符可读,则继续循环
MOV AH, 0
INT 16H
CMP AL, KBEsc
JNZ again ;若按键不是Escape,则继续循环
.EXIT 0
END
例8.4 编写一个输入密码的程序,该程序的具体要求如下:
1、每输入一个字符,显示字符"#"表示之;
2、密码最多只有10个字符,多余的按键被丢弃;
3、若输入的字符串为"HELLO",则以蓝色显示"Welcome…",否则,以闪烁、亮红色在显示"Invalid Password"。
解:
.MODEL SMALL
.DATA
CR EQU 0DH
MSG1 DB "Welcome..."
MSG2 DB "Invalid Password"
PSW1 DB "HELLO"
BUFF DB 10 DUP(?)
.CODE
.STARTUP
MOV AX, DS
MOV ES, AX
XOR BX, BX
again:
MOV AH, 0H
INT 16H ;从键盘接受字符输入
CMP AL, CR
JZ next ;若按“回车“键,则结束密码输入
CMP BX, 10
JZ again ;若已接受了10个字符,则丢弃随后的字符
.IF AL>='a' && AL<=’z’
SUB AL, 20H
.ENDIF
MOV BUFF[BX], AL
INC BX ;保存当前输入,并移动有关指针
MOV DL, '#'
MOV AH, 2
INT 21H ;在屏幕上显示字符”#”
JMP again
next:
CALL Clear ;清屏幕,见例8.2中的过程定义
CMP BX, 5
JNZ error ;若输入的字符串长度不为5,则密码错误
LEA SI, PSW1
LEA DI, BUFF
MOV CX, BX
CLD
REPE CMPSB ;比较字符串PSW1和BUFF
.IF ZERO? ;若字符串的相应字符相同
MOV BP, OFFSET MSG1 ;显示字符串首地址
MOV BL, 09H ;显示字符颜色:蓝色
MOV CX, 0AH ;显示字符串长度:10
.ELSE
MOV BP, OFFSET MSG2 ;显示字符串首地址
MOV BL, 8CH ;显示字符颜色:闪烁、亮红色
MOV CX, 10H ;显示字符串长度:16
.ENDIF
MOV AL, 0
MOV BH, 0
MOV DH, 5
MOV DL, 20 ;在位置(5,20)的位置开始显示字符串
MOV AH, 13H
INT 10H ;使用中断10H之功能13H来显示字符串
.EXIT 0
END
例8.5 在256色320×200的图形显示模式下,从屏幕最左边向最右边,依次画竖线(从顶到底),线的颜色从1依次加1。要求用中断调用的方法来画线。
解:
.MODEL SMALL
.DATA
mode DB ? ;保存当前显示模式
.CODE
VLine PROC Near USES AX BX DX ;画一条竖线,CX—竖线所在的列,AL—线的颜色
MOV DX, 0
MOV BH, 0
MOV AH, 0CH
draw:
VLine INT 10H
INC DX
CMP DX, 200
JL draw
RET
ENDP
.STARTUP
MOV AH, 0FH
INT 10H
MOV mode, AL ;保存当前显示模式,在程序结束前恢复之
MOV AH, 0
MOV AL, 13H
INT 10H ;设置256色320×200的图形显示模式
MOV CX, 0
MOV AL, 01H ;CX=线所在列,AL=线的颜色
draw:
CALL VLine
INC AL
INC CX
CMP CX, 320
JL draw ;从左到右画320条竖线
MOV AH, 0
INT 16H ;等待一个按键
MOV AL, mode
MOV AH, 0
INT 10H ;恢复原来的屏幕显示模式
.EXIT 0
END
例8.6 在256色320×200的图形显示模式下,从屏幕顶到屏幕底依次画横线(从最左边到最右边),线的颜色从1依次加1。要求用直接操作显示缓冲区的方法来画线。
解:
.MODEL SMALL
.DATA
mode DB ? ;保存当前显示模式
.CODE
HLine PROC Near USES CX DI ;画一条横线,DI—横线所在行,AL—线的颜色
IMUL DI, 320 ;跳过前面横所对应的字节,每行320个字节
MOV CX, 320
REP STOSB ;重复设置AL的值
RET
HLine ENDP
.STARTUP
MOV AH, 0FH
INT 10H
MOV mode, AL ;保存当前显示模式,在程序结束前恢复之
MOV AH, 0
MOV AL, 13H
INT 10H ;设置256色320×200的图形显示模式
MOV AX, 0A000H
MOV ES, AX ;图形模式的段地址为0A000H
CLD
MOV DI, 0
MOV AL, 01H ;CX=线所在列,AL=线的颜色
draw:
CALL HLine
INC AL
INC DI
CMP DI, 200
JL draw ;从上到下画200条横线
MOV AH, 0
INT 16H ;等待一个按键
MOV AL, mode
MOV AH, 0
INT 10H ;恢复原来的屏幕显示模式
.EXIT 0
END