汇编语言高手:微机原理课程设计---显示日期或时间2
发布网友
发布时间:2023-09-17 05:51
我来回答
共3个回答
热心网友
时间:2023-10-11 13:31
; 题目名称:显示系统日期和时间
; 题目来源:http://zhidao.baidu.com/question/130808124.html
; 程序特点:本程序未使用常规的BIOS中断调用和DOS功能调用的方法接收按键,而是直接判断键盘缓冲区的方法接收按键,
; 避免了在接收按键期间日期或时间停止显示(不更新)的重要弊端,尤其是时间秒的更新,尤为明显;对于显示日期,只
; 有在午夜前几秒进入显示日期状态,且不改变程序运行状态的前提下,方能看出日期显示的变更。
; 本程序在MASMPlus 1.2集成环境下通过编译,经过调试,运行正确。
Code Segment
Assume CS:Code,DS:Code
CR equ 13
LF equ 10
BiosDataSeg equ 0040H ; Bios data area segment
Buffer_Head equ 001AH ; Pointer to head of keyboard buffer
Buffer_Tail equ 001CH ; Pointer to tail of keyboard buffer
KB_BufferBeg equ 001EH ; head address of keyboard buffer
; -------------------------------------
; 功能:显示指定地址(Str_Addr)的字符串
; 入口:
; Str_Addr=字符串地址(要求在数据段)
; 用法: Output Str_Addr
; 用法举例:Output PromptStr
Output MACRO Str_Addr
push ax
lea dx,Str_Addr
mov ah,9
int 21h
pop ax
EndM
; -------------------------------------
; 功能:取光标位置
; 入口:无
; 出口:DH=行号,DL=列号
GetCursor Proc Near
PUSH AX
PUSH BX
XOR BX,BX
MOV AH,3
INT 10H
MOV cs:Cursor_Row,DH
MOV cs:Cursor_Col,DL
POP BX
POP AX
RET
Cursor_Row DB ?
Cursor_Col DB ?
GetCursor EndP
; -------------------------------------
; 功能:置光标位置
; 入口:Cursor_Row=行坐标; Cursor_Col: 列坐标)
SetCursor Proc Near
PUSH CX
PUSH BX
PUSH AX
MOV DH,cs:Cursor_Row
MOV DL,cs:Cursor_Col
XOR BX,BX
MOV AH,2
INT 10H
POP AX
POP BX
POP CX
RET
SetCursor EndP
; -------------------------------------
; 功能:置光标属性
SetCursor_Attr Proc Near
push cx
push ax
mov cx,cs:Cursor_Attr
mov ch,cl
or ch,20h
mov ah,1 ;设置光标属性
int 10h
pop ax
pop cx
ret
SetCursor_Attr EndP
; -------------------------------------
; 入口:AL=cmos内存端口号,DI=对应的ASCII码保存地址
BCD_ASCII Proc Near ;将组合BCD码转换成对应的ASCII码
out 70h,al
in al,71h
xor ah,ah
mov cx,4
shl ax,cl
shr al,cl
or ax,3030h
xchg ah,al
stosw ;保存对应的ASCII码
ret
BCD_ASCII EndP
; -------------------------------------
; 显示系统日期
Disp_Date proc Near
call SetCursor_Attr ;使光标不可见
push ds
push cs
pop ds
mov Status,'D' ;修改程序状态为:显示系统日期
lea di,@@Date ;日期字符串地址
mov al,32h ;日期的世纪数
call BCD_ASCII
mov al,9 ;年份
call BCD_ASCII
inc di
mov al,8 ;月份
call BCD_ASCII
inc di
mov al,7 ;日号
call BCD_ASCII
mov dx,Cursor_Sele
add dh,4
xor dl,dl
mov Cursor_Row,dh
mov Cursor_Col,dl
call SetCursor
Output @@Date ;显示系统日期
pop ds
ret
Disp_Date Endp
; -------------------------------------
; 显示系统时间
Disp_Time proc Near
call SetCursor_Attr ;使光标不可见
push ds
push cs
pop ds
mov Status,'T' ;修改程序状态为:显示系统时间
lea di,@@Time ;时间字符串地址
mov al,4 ;时
call BCD_ASCII
inc di
mov al,2 ;分
call BCD_ASCII
inc di
xor al,al ;秒
call BCD_ASCII
mov dx,Cursor_Sele
add dh,6
xor dl,dl
mov Cursor_Row,dh
mov Cursor_Col,dl
call SetCursor
Output @@Time ;显示系统时间
pop ds
ret
Disp_Time Endp
; -------------------------------------
Prompt_Menu db 'Date',CR,LF
db 'Time',CR,LF
db 'Quit',CR,LF
db 'Please select:$'
Status db '?' ;程序状态标志
Cursor_Sele dw ? ;保存光标位置
Cursor_Attr dw ? ;保存光标属性(大小、闪烁)
@@Date db ' / / $'
@@Time db ' : : $'
Press_Key db 7,CR,LF,CR,LF,'The complated. Press any key to exit...$' ;操作完成按任意键结束程序提示信息
Start: push cs
pop ds
push cs
pop es ;使数据段、附加段与代码段同段
Output Prompt_Menu ;菜单地址
call GetCursor ;取光标位置
mov Cursor_Sele,dx
mov Cursor_Attr,cx
mov ax,BiosDataSeg ;Bios data area segment
mov ds,ax
mov si,Buffer_Head ; Pointer to head of keyboard buffer
mov WORD ptr [si],KB_BufferBeg ; head address of keyboard buffer
mov WORD ptr [si][2],KB_BufferBeg
@@Select: mov dx,cs:Cursor_Sele
mov cs:Cursor_Row,dh
mov cs:Cursor_Col,dl
call SetCursor ;置光标位置
Wait_Press: mov cx,cs:Cursor_Attr ;取光标属性
mov ah,1 ;设置光标属性
int 10h
mov si,Buffer_Tail
mov ax,[si]
mov si,Buffer_Head
cmp ax,WORD ptr [si]
jz Check_Status ;没有按键,检查程序状态标志
mov si,[si] ;第一个未处理按键地址
mov ax,[si] ;读取按键
mov si,Buffer_Head ; Pointer to head of keyboard buffer
mov WORD ptr [si],KB_BufferBeg ; head address of keyboard buffer
mov WORD ptr [si][2],KB_BufferBeg
push ax
mov dl,al
mov ah,2
int 21h
pop ax
and al,0dfh ;转换成大写,使大小写不敏感
cmp al,'Q'
jz Exit_Proc
cmp al,'D'
jnz $+7
call Disp_Date ;显示系统日期
jmp @@Select
cmp al,'T'
jnz @@Select
call Disp_Time ;显示系统时间
jmp @@Select
Check_Status: mov al,cs:Status ;取程序状态标志
cmp al,'?' ;尚未执行每个功能
jz Wait_Press ;等待按键
cmp al,'D' ;当前处于显示系统日期状态?
jnz $+7 ;不是
call Disp_Date
jmp @@Select ;等待按键
cmp al,'T' ;当前处于显示系统时间状态?
jnz $+5 ;不是
call Disp_Time
jmp @@Select ;等待按键
; -------------------------------------
Exit_Proc: push cs
pop ds
Output Press_Key ;提示操作完成,按任意键结束程序
mov ah,1
int 21h
mov ah,4ch ;结束程序
int 21h
Code ENDS
END Start ;编译到此结束
热心网友
时间:2023-10-11 13:31
要得到系统日期时间,可以通过1AH中断的2号盒4号功能,如果你喜欢,也可以通过读写端口得到,然后把那些压缩BCD码解析出来
要源程序的话,分是不是太少了?
---------------------------------------------------------
;MASM编译通过
;运行正确
STACK SEGMENT STACK
STACKH DB 20H DUP(?)
STSIZE EQU $-STACKH
STACK ENDS
CODE SEGMENT
ASSUME CS:CODE,SS:STACK;,DS:DATA
START:
MOV AX,STACK
MOV SS,AX
MOV SP,STSIZE
SCANK:;扫描键盘输入
XOR AX,AX
INT 16H
CMP AL,'D'
JNE CHKT
CALL DSPD;响应按键'D'
JMP SCANK
CHKT:
CMP AL,'T'
JNE CHKQ
CALL DSPT;响应按键'T'
JMP SCANK
CHKQ:
;可以添加代码以响应其他按键
;否则,它们将被忽略
CMP AL,'Q'
JE EXIT;响应按键'Q'
JMP SCANK
EXIT:
MOV AX,4C00H
INT 21H
;功能: 显示一个压缩BCD码
;入口: BH=页号
; BL=前景色
; AL=压缩BCD码
DSPBCD PROC
PUSH AX
PUSH CX
MOV CL,4
MOV AH,0
ROR AX,CL
SHR AH,CL
OR AX,3030H
MOV CH,AH
MOV AH,0EH
INT 10H
MOV AL,CH
INT 10H
POP CX
POP AX
RET
DSPBCD ENDP
;功能: 显示系统日期
;入口: BH=页号,BL=前景色
; DSPD直接传给DSPBCD
DSPD PROC
PUSH AX
PUSH CX
MOV AL,9
MOV CX,3
GETD:
PUSH AX
OUT 70H,AL
IN AL,71H
CALL DSPBCD ;显示一个日期项,如:年
MOV AX,0E2EH ;'.'的ASCII码为2E
INT 10H ;显示一个分隔符'.'
POP AX
DEC AL
LOOP GETD
POP CX
POP AX
RET
DSPD ENDP
;功能: 显示系统时间
;入口: BH=页号,BL=前景色
; DSPT直接传给DSPBCD
DSPT PROC
PUSH AX
PUSH CX
MOV AL,04H
MOV CX,3
GETT:
PUSH AX
OUT 70H,AL
IN AL,71H
CALL DSPBCD ;显示一个日期项,如:日
MOV AX,0E3AH ;':'的ASCII码为3A
INT 10H ;显示一个分隔符':'
POP AX
SUB AL,2
LOOP GETT
POP CX
POP AX
RET
DSPT ENDP
CODE ENDS
END START
热心网友
时间:2023-10-11 13:32
参考如下:
DATEDISPLAY PROC NEAR
MOV AH,2AH ;取当前系统日期
INT 21H
MOV AX,CX ;送年份入AX作为被除数 【年份存在CX中】
MOV BX,10 ;(BX)=10
LEA SI,DATEDIS+4 ;使SI指向年的最后一位 【从0开始数】
MOV CX,4 ;(CX)=4 年的位数,循环4次
PUSH DX ;DX入栈,保存月日
TAB:
XOR DX,DX ;DX清零,存余数
DIV BX ;(DX,AX)/BX,商送AX,余数送DX
ADD DL, 30H ;余数与30H相加变为字符的ASCII码
MOV [SI], DL ;余数送入SI所指向的字节区
DEC SI ;SI减一
LOOP TAB ;循环4次
POP DX ;DX还原
MOV AL, DL ;日送AL【日存在DL中】
XOR AH, AH ;AH清零
DIV BL ;AX/BL,商送AL,余数送AH【AL为十位,AH为个位】
ADD AX, 3030H ;转变为数字字符的ASCII码
LEA SI, DATEDIS+9 ;使SI指向日的十位
MOV [SI], AX ;(AX)送SI所指向的字节区
MOV AL, DH ;月送AL 【月存在DH中】
XOR AH, AH ;AH清零
DIV BL ;AX/BL,商送AL,余数送AH【AL为十位,AH为个位】
ADD AX, 3030H ;转变为数字字符的ASCII码
LEA SI, DATEDIS+6 ;使SI指向月的十位
MOV [SI], AX ;(AX)送SI所指向的字节区
SHOW DATEDIS ;显示日期
RET ;调用后返回
DATEDISPLAY ENDP
;*********时间显示子程序*********
TIMEDISPLAY PROC NEAR
MOV AH,2CH
INT 21H
MOV BX,10
MOV AL,CH ;CH存时
XOR AH,AH
DIV BL
ADD AX,3030H
LEA DI,TIMEDIS+1
MOV [DI],AX
MOV AL,CL ;CL存分
XOR AH,AH
DIV BL
ADD AX,3030H
LEA DI,TIMEDIS+4
MOV [DI],AX
MOV AL,DH ;DH存秒
XOR AH,AH
DIV BL
ADD AX,3030H
LEA DI,TIMEDIS+7
MOV [DI],AX
SHOW TIMEDIS
RET ;时间调用返回
TIMEDISPLAY ENDP
CODE ENDS
END START