解:在文本显示方式下,每行显示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