148 lines
2.6 KiB
NASM
148 lines
2.6 KiB
NASM
; 实验九 - 时钟显示程序
|
||
; 功能: 实时显示系统时间
|
||
; 模式: 文本模式 80x25 彩色
|
||
|
||
.MODEL SMALL
|
||
.DATA
|
||
TIME_FORMAT DB '00:00:00', '$'
|
||
TITLE DB '=== Real Time Clock ===', 0DH, 0AH, '$'
|
||
DATE_FMT DB 'Date: 20XX/XX/XX', '$'
|
||
|
||
.CODE
|
||
.STARTUP
|
||
MOV AX, @DATA
|
||
MOV DS, AX
|
||
|
||
MAIN_LOOP:
|
||
; 读取当前时间 (INT 1AH, AH=02H)
|
||
MOV AH, 02H
|
||
INT 1AH
|
||
; DL=日(BCD), DH=时(BCD), CL=分(BCD), CH=秒(BCD)
|
||
|
||
; 将时、分、秒分别转换为ASCII字符串
|
||
; 小时的BCD码在DH中
|
||
MOV AL, DH
|
||
CALL BCD_TO_STR
|
||
MOV [TIME_FORMAT], AH
|
||
MOV [TIME_FORMAT+1], AL
|
||
|
||
; 分钟的BCD码在CL中
|
||
MOV AL, CL
|
||
CALL BCD_TO_STR
|
||
MOV [TIME_FORMAT+3], AH
|
||
MOV [TIME_FORMAT+4], AL
|
||
|
||
; 秒的BCD码在CH中
|
||
MOV AL, CH
|
||
CALL BCD_TO_STR
|
||
MOV [TIME_FORMAT+6], AH
|
||
MOV [TIME_FORMAT+7], AL
|
||
|
||
; 读取当前日期 (INT 1AH, AH=04H)
|
||
MOV AH, 04H
|
||
INT 1AH
|
||
; DL=日, DH=月, CL=年(BCD), CH=世纪
|
||
|
||
; 转换日期
|
||
MOV AL, CH ; 世纪
|
||
CALL BCD_TO_STR
|
||
MOV [DATE_FMT+8], AH
|
||
MOV [DATE_FMT+9], AL
|
||
|
||
MOV AL, CL ; 年
|
||
CALL BCD_TO_STR
|
||
MOV [DATE_FMT+12], AH
|
||
MOV [DATE_FMT+13], AL
|
||
|
||
MOV AL, DH ; 月
|
||
CALL BCD_TO_STR
|
||
MOV [DATE_FMT+15], AH
|
||
MOV [DATE_FMT+16], AL
|
||
|
||
MOV AL, DL ; 日
|
||
CALL BCD_TO_STR
|
||
MOV [DATE_FMT+18], AH
|
||
MOV [DATE_FMT+19], AL
|
||
|
||
; 清除屏幕
|
||
MOV AX, 0600H
|
||
MOV BH, 07H
|
||
MOV CX, 0000H
|
||
MOV DX, 184FH
|
||
INT 10H
|
||
|
||
; 设置光标位置
|
||
MOV AH, 02H
|
||
MOV BH, 0
|
||
MOV DH, 10
|
||
MOV DL, 35
|
||
INT 10H
|
||
|
||
; 显示标题
|
||
LEA DX, TITLE
|
||
MOV AH, 09H
|
||
INT 21H
|
||
|
||
; 显示时间
|
||
MOV AH, 02H
|
||
MOV BH, 0
|
||
MOV DH, 12
|
||
MOV DL, 35
|
||
INT 10H
|
||
|
||
LEA DX, TIME_FORMAT
|
||
MOV AH, 09H
|
||
INT 21H
|
||
|
||
; 显示日期
|
||
MOV AH, 02H
|
||
MOV BH, 0
|
||
MOV DH, 14
|
||
MOV DL, 32
|
||
INT 10H
|
||
|
||
LEA DX, DATE_FMT
|
||
MOV AH, 09H
|
||
INT 21H
|
||
|
||
; 延时1秒
|
||
MOV CX, 0
|
||
MOV DX, 0
|
||
MOV AH, 86H
|
||
INT 15H
|
||
|
||
; 检查是否按下ESC键退出
|
||
MOV AH, 01H
|
||
INT 16H
|
||
JZ MAIN_LOOP ; 无按键继续
|
||
|
||
; 有按键,读取并检查是否是ESC
|
||
MOV AH, 00H
|
||
INT 16H
|
||
CMP AH, 01H ; ESC键
|
||
JNE MAIN_LOOP ; 不是ESC继续
|
||
|
||
.EXIT
|
||
|
||
; 子程序: 将AL中的BCD码转换为ASCII字符
|
||
; 输入: AL = BCD码 (如 09H -> '0','9')
|
||
; 输出: AH = 高位字符, AL = 低位字符
|
||
BCD_TO_STR PROC
|
||
PUSH DX
|
||
|
||
MOV AH, AL
|
||
AND AH, 0F0H ; 提取高位
|
||
MOV DL, 4
|
||
SHR AH, DL
|
||
ADD AH, '0'
|
||
|
||
MOV DL, AL
|
||
AND DL, 0FH ; 提取低位
|
||
ADD DL, '0'
|
||
MOV AL, DL
|
||
|
||
POP DX
|
||
RET
|
||
BCD_TO_STR ENDP
|
||
|
||
END |