做一个与电脑同步的时间,并且当跳到指定时间时,能显示一行字符串。
附上已有的程序,请高手帮忙!!
;---------------------------------------------------------------定义数据段
DATA SEGMENT
dw 0,0
MESS1 DB 0DH,0AH,'------------------------',0DH,0AH ;0DH,0AH是回车换行的意思
DB '| 1- Working schedule |',0DH,0AH
DB '| 2- Time to ring a bell |',0DH,0AH ;主菜单
DB '| 3- Exit |',0DH,0AH
DB '| 4- return to the main menu|',0DH,0AH
DB '----------------------- ',0DH,0AH,'$'
MESS2 DB 0DH,0AH,'------------------------',0DH,0AH ;0DH,0AH是回车换行的意思
DB '| Working schedule |',0DH,0AH
DB '| 8:25 Morning Exercises |',0DH,0AH
DB '| 9:40 The first class |',0DH,0AH ;子菜单1
DB '| 10:20 The first class is over |',0DH,0AH
DB '| 10:40 The sceond class |',0DH,0AH
DB '| 11:25 The second class is over |',0DH,0AH
DB '----------------------- ',0DH,0AH,'$'
MSG DB 0DH,0AH,' PRESS [1 OR 2 OR 3 or 4 ]',0DH,0AH,'$' ;提示信息
MSG1 DB 0DH,0AH,'press "4" to return main menu',0DH,0AH,'$' ;提示信息
STRING DB 'SCREEN' ;???
LEN EQU $-STRING
DATA ENDS
;---------------------------------------------------------------定义堆栈段
STACK segment
db 128 dup(0)
STACK ends
;---------------------------------------------------------------定义代码段
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,SS:STACK
MAIN PROC FAR ;主程序 子程序可段间调用
PUSH DS ;将ds寄存器压入栈 把返回操作系统的入口压入堆栈
MOV AX,0 ;将0传入ax寄存器
PUSH AX ;将ax压入栈
MOV AX,DATA
MOV DS,AX
START1: MOV AH,09H ;显示主菜单 MESS1
LEA DX, MESS1 ;LEA是目标地址传送指令,将一个近地址指针写入到指定的寄存器
INT 21H ;MOV AH,09H INT 21H 是在屏幕显示字符串 该字符串要以“$”结束
MOV AH,09H
LEA DX, MSG ;显示提示信息 MSG
INT 21H
LOP1: MOV AH,08H ;从标准输入设备输入一个字符,在此是用户输入所选菜单
INT 21H
;-------------------------------判断从键盘输入的选项
PUSH AX
CMP AL,'4'
JZ C4
POP AX
PUSH AX
CMP AL,'1' ; JZ (相等的时候跳转)
JZ C1 ;若等于1,则跳转到C1
POP AX ;否则AX出栈,并与2比较
PUSH AX
CMP AL,'2'
JZ C2
POP AX
PUSH AX
CMP AL,'3'
JZ C3 ;若等于3,则跳转到C3
JMP LOP1 ;否则跳转到LOP1,即重新输入一个字符(1/2/3/4)
;-----------------------------------------------------------------------
;此为前面所要跳转的程序
C1: MOV BH,27H
CALL COLOR
START2: MOV AH,09H
LEA DX, MESS2 ;LEA是目标地址传送指令,将一个近地址指针写入到指定的寄存器
INT 21H ;MOV 09H,INT 21H 是在屏幕显示字符串 该字符串要以“$”结束
MOV AH,09H
LEA DX, MSG1 ;显示"返回主菜单"的提示信息
INT 21H
JMP LOP1
C2: MOV BH,37H
CALL COLOR
JMP begin
C3: MOV BH,07H
CALL COLOR
MOV AX,4C00H
INT 21H
C4: MOV BH,27H
CALL COLOR
JMP START1
MAIN ENDP
;-----------------------------------------------
COLOR PROC NEAR
MOV AH,6
MOV AL,0
MOV CX,0
MOV DX,184FH
INT 10H
RET
COLOR ENDP
COL1 PROC NEAR
MOV AX,0003H
INT 10H
MOV BX,SEG STRING
MOV ES,BX
LEA BP,STRING
MOV CX,LEN
MOV BL,41H
MOV AL,1
MOV DX,0
MOV AH,13H
INT 10
RET
COL1 ENDP
;---------------------------------------------时间显示部分
begin:
mov bx,0
mov ax,0b800h
mov es,ax
;-------------初始化数据段
mov ax,data
mov ds,ax
;------------ 初始化堆栈段
mov ax,stack
mov ss,ax
mov sp,128
;------------ 将9号中断向量保存在ds:[0]~ds:[3]单元中
push es
mov ax,0
mov es,ax
push es:[9*4]
pop ds:[0]
push es:[9*4+2]
pop ds:[2]
;---------------------
mov ax,offset int9 ;取得自定义9号中断向量的偏移地址
cli ;不允许产生中断
mov es:[9*4],ax ;设置新的9号中断向量所在地址
mov es:[9*4+2],cs
sti ;允许产生中断
pop es
;---------------------
mov cx,4000
s:
mov es:[di], byte ptr 0
inc di ;此循环体的作用是清屏
loop s
;-------------------
mov cx,17
a:
mov es:[160*12][2*30+1][bx],byte ptr 1
add bx,2
loop a
;此循环体的作用是初始化17个显示在屏幕上的相关内容
;[包括年月日、时分秒以及5个'/'号]的颜色属性为蓝色
;如果缺少此循环体则为黑色[而清屏后屏幕的颜色为黑色]
;为黑色时则第一次看不到显示的时间信息,只有按了相关键时才看得到。
;---------------- 初始化读取CMOS RAM中的第9号单元[即:'年份'所在单元]
t:
mov bx,0
mov cx,3
mov dh,9
;-----------------
s1:
mov al,dh
out 70h,al ;向70号端口写入要访问的单元地址[第一次是9号[即年份所在]单元]
dec dh
in al,71h ;从71号端口读取指定单元中的数据[因为是三次循环] 所以[第一次是年份、第二次是月份、第三次是日期号] 关于时、分、秒的读取方法在循环体s3处与此类似,下面将不再赘述
push cx
mov cl,4
mov dl,al
shr al,cl ;第一次循环时是获取年份的十位数
add al,30h ;并使其成为可显示的十进数
mov es:[160*12][2*30][bx],al
and dl,00001111b ;第一次循环时是获取年份的个位数
add dl,30h ;并使其成为可显示的十进数
;关于月份、日期号及在循环体s3处的作用[:时、分、秒的读取方法]
;与此类似,因此不再赘述
mov es:[160*12+2*30+2][bx],dl
mov es:[160*12][2*30+4][bx],byte ptr '/'
add bx,6
pop cx
loop s1 ;s1循环体的作用是分别取得'年'、'月'、'日'的内容
;----------------------
mov cx,3
mov dh,4
s3:
mov al,dh
out 70h,al
in al,71h
mov dl,al
push cx
mov cl,4
shr al,cl
add al,30h
and dl,00001111b
add dl,30h
mov bp,1
mov es:[160*12][2*30][bx],al
mov es:[160*12][2*30][bx].2,dl
mov es:[160*12][2*30][bx].4,byte ptr '/'
add bx,6
sub dh,2
pop cx
loop s3 ;s3循环体的作用是分别取得'时'、'分'、'秒'的内容
mov es:[160*12][2*30+4][bx-6].1,byte ptr 0
jmp t ;再一次跳到标号t处,实现循环读取 年/月/日/时/分/秒 的内容 以达到动态显示系统时间的效果
;-----------------
i8:
pop es
pop es
pop es
pop bx
pop ax
iret
mov ax,0
mov es,ax
push ds:[0]
pop es:[9*4]
push ds:[2]
pop es:[9*4+2] ;以上几句的作用是将真的9号中断向量进行恢复
mov ax,4c00h
int 21h
;--------------------
int9:
push ax
push bx
push es
mov ax,0b800h
mov es,ax
in al,60h ;从键盘缓冲区读取所按下的键的扫描码
pushf
pushf
pop bx
and bh,11111100b
push bx
popf
;这个程序是动态显示系统时间的
;其中,运行中按上,下,左,右,pageup,pagedown键分别可调整年月日时分秒的显示
;属性. caps lock键控制分割符"\"显示属性,Esc键退出
call dword ptr ds:[0] ;真INT9例程的返回
;---------------- 是否按了'上'方向键
cmp al,48h
jne i1
inc byte ptr es:[160*12][2*30+1]
inc byte ptr es:[160*12][2*30+3]
;以上2句为修改年份的颜色属性[+1]
jmp intend ;直接结束一次中断,以避免修改其它单元内容
;-------------- 是否按了'左'方向键
i1:
cmp al,4bh
jne i2
inc byte ptr es:[160*12][2*30+7]
inc byte ptr es:[160*12][2*30+9]
;以上2句为修改月份的颜色属性[+1]
jmp intend ;直接结束一次中断,以避免修改其它单元内容
;---------------是否按了'下'方向键
i2:
cmp al,50h
jne i3
inc byte ptr es:[160*12][2*30+13]
inc byte ptr es:[160*12][2*30+15]
;以上2句为修改日期的颜色属性[+1]
jmp intend ;直接结束一次中断,以避免修改其它单元内容
;---------------- 是否按了'右'方向键
i3:
cmp al,4dh
jne i4
inc byte ptr es:[160*12][2*30+19]
inc byte ptr es:[160*12][2*30+21]
;以上2句为修改'时'的颜色属性[+1]
jmp intend ;直接结束一次中断,以避免修改其它单元内容
;----------------- 是否按了PageUp键
i4:
cmp al,49h
jne i5
inc byte ptr es:[160*12][2*30+25]
inc byte ptr es:[160*12][2*30+27]
;以上2句为修改'分'的颜色属性[+1]
jmp intend ;直接结束一次中断,以避免修改其它单元内容
;---------------- 是否按了PageDown键
i5:
cmp al,51h
jne i6
inc byte ptr es:[160*12][2*30+31]
inc byte ptr es:[160*12][2*30+33]
;以上2句为修改'秒'的颜色属性[+1]
jmp intend ;直接结束一次中断,以避免修改其它单元内容
;---------------- 是否按了Caps Lock键
i6:
cmp al,3ah
jne i7
inc byte ptr es:[160*12][2*30+5]
inc byte ptr es:[160*12][2*30+11]
inc byte ptr es:[160*12][2*30+17]
inc byte ptr es:[160*12][2*30+23]
inc byte ptr es:[160*12][2*30+29]
;以上5句是将5个'/'号的颜色属性加1
jmp intend ;直接结束一次中断
;--------------- 是否按了Esc键
i7:
cmp al,01h
jne intend
jmp far ptr i8 ;自定义中断[即假的9号中断例程]结束后跳至
;标号i8处[以恢复真的9号中断例程的向量地址]
;-----------------------
intend:
pop es
pop bx
pop ax
iret ;假INT9例程的返回
;-------------------
CODE ENDS
END MAIN