ITEEDU

5、屏幕输出的举例
例8.2 用直接写屏方式在屏幕第5行、第10列以黄色(0EH)显示字符串"Hello"。

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