160 lines
2.5 KiB
NASM
160 lines
2.5 KiB
NASM
; 实验九 - 键盘计数器程序
|
||
; 功能: 统计按键次数并显示
|
||
; 模式: 文本模式 80x25 彩色
|
||
|
||
.MODEL SMALL
|
||
.DATA
|
||
TITLE_MSG DB '=== Keyboard Counter ===', 0DH, 0AH, '$'
|
||
COUNT_MSG DB 'Key presses: ', '$'
|
||
EXIT_MSG DB 0DH, 0AH, 'Press ESC to exit.', '$'
|
||
COUNT_STR DB '00000', '$'
|
||
CRLF DB 0DH, 0AH, '$'
|
||
|
||
.CODE
|
||
.STARTUP
|
||
MOV AX, @DATA
|
||
MOV DS, AX
|
||
|
||
; 清除屏幕
|
||
MOV AX, 0600H
|
||
MOV BH, 07H
|
||
MOV CX, 0000H
|
||
MOV DX, 184FH
|
||
INT 10H
|
||
|
||
; 显示标题
|
||
LEA DX, TITLE_MSG
|
||
MOV AH, 09H
|
||
INT 21H
|
||
|
||
; 显示计数初始值
|
||
LEA DX, COUNT_MSG
|
||
MOV AH, 09H
|
||
INT 21H
|
||
|
||
LEA DX, COUNT_STR
|
||
MOV AH, 09H
|
||
INT 21H
|
||
|
||
; 初始化计数器
|
||
XOR CX, CX ; CX = 0
|
||
|
||
COUNT_LOOP:
|
||
; 检查是否有按键按下 (INT 16H, AH=01H)
|
||
MOV AH, 01H
|
||
INT 16H
|
||
JZ NO_KEY ; ZF=1 表示无按键
|
||
|
||
; 读取按键 (INT 16H, AH=00H)
|
||
MOV AH, 00H
|
||
INT 16H
|
||
|
||
; 检查是否是ESC键
|
||
CMP AH, 01H ; ESC的扫描码
|
||
JE EXIT_PROGRAM
|
||
|
||
; 计数器加1
|
||
INC CX
|
||
|
||
; 将计数器值转换为字符串
|
||
CALL WORD_TO_STR
|
||
|
||
; 清除当前行
|
||
MOV AH, 02H
|
||
MOV BH, 0
|
||
MOV DH, 2
|
||
MOV DL, 0
|
||
INT 10H
|
||
|
||
; 显示当前计数
|
||
MOV AH, 13H
|
||
MOV AL, 01H
|
||
MOV BH, 0
|
||
MOV BL, 0FH
|
||
MOV DX, OFFSET COUNT_MSG
|
||
MOV CX, 12
|
||
PUSH DS
|
||
POP ES
|
||
MOV BP, DX
|
||
INT 10H
|
||
|
||
; 重新显示计数
|
||
MOV AH, 02H
|
||
MOV BH, 0
|
||
MOV DH, 2
|
||
MOV DL, 12
|
||
INT 10H
|
||
|
||
LEA DX, COUNT_STR
|
||
MOV AH, 09H
|
||
INT 21H
|
||
|
||
NO_KEY:
|
||
; 短暂延时,避免过度消耗CPU
|
||
MOV CX, 0FFFFH
|
||
DELAY:
|
||
LOOP DELAY
|
||
|
||
JMP COUNT_LOOP
|
||
|
||
EXIT_PROGRAM:
|
||
; 按下ESC,退出程序
|
||
MOV AH, 00H
|
||
INT 16H
|
||
|
||
; 清除屏幕
|
||
MOV AX, 0600H
|
||
MOV BH, 07H
|
||
MOV CX, 0000H
|
||
MOV DX, 184FH
|
||
INT 10H
|
||
|
||
.EXIT
|
||
|
||
; 子程序: 将CX中的16位数值转换为字符串
|
||
WORD_TO_STR PROC
|
||
PUSH AX
|
||
PUSH BX
|
||
PUSH DX
|
||
|
||
; 将数字分解为万位、千位、百位、十位、个位
|
||
MOV AX, CX
|
||
MOV BX, 10
|
||
|
||
; 个位
|
||
MOV DX, 0
|
||
DIV BX
|
||
ADD DL, '0'
|
||
MOV [COUNT_STR+4], DL
|
||
|
||
; 十位
|
||
MOV DX, 0
|
||
DIV BX
|
||
ADD DL, '0'
|
||
MOV [COUNT_STR+3], DL
|
||
|
||
; 百位
|
||
MOV DX, 0
|
||
DIV BX
|
||
ADD DL, '0'
|
||
MOV [COUNT_STR+2], DL
|
||
|
||
; 千位
|
||
MOV DX, 0
|
||
DIV BX
|
||
ADD DL, '0'
|
||
MOV [COUNT_STR+1], DL
|
||
|
||
; 万位
|
||
MOV DX, 0
|
||
DIV BX
|
||
ADD DL, '0'
|
||
MOV [COUNT_STR], DL
|
||
|
||
POP DX
|
||
POP BX
|
||
POP AX
|
||
RET
|
||
WORD_TO_STR ENDP
|
||
|
||
END |