📄 32060624_王克_asmhomework_5_3.asm
字号:
; 32060624___王克__ASMHomeWork__5
;----------------------------------------------------------------
; ╭══════┤ 32060624___王克__ITRunner!! ├═════╮
; ║ ║
; ║ ║
; ║ ★ 汇编语言 第五次作业 ★ ║
; ║ |---------------------------------------------| ║
; ║ DOS时钟小程序 ║
; ║ 2004.12.25 ║
; ║ ║
; ╰ ════════════════════════════╯
;汇编程序说明:
;2004.12.24 night 基本功能已经实现 1. 可以在DOS下每秒显示一次。2. 会出现CPU出错信息,??? 3. 未对前景背景美化
;2004.12.28 night 功能完成 1. 加入星期字符串 2.改进输出方式,色彩动态变化,改用BIOS的中断 3.增添时间框,更加美观
;━┅━┅━┅━┅━┅━┅━┅━┅━━┅━┅━┅━┅━┅━┅━┅━━┅━┅━━┅━
;************************************************************************
;macros for more convenient
print_string macro string,pos,len
push ax
push bx
push cx
push dx
push es
push bp
;mov dx,offset string //?????
;mov ah,9h
;int 21h
push ds
pop es
mov bp,offset string
xor bh,bh
mov bl,_color
mov dx,pos
mov cx,len
mov ax,1300h
int 10h
pop bp
pop es
pop dx
pop cx
pop bx
pop ax
endm
print_char macro char
push ax
push bx
push cx
push dx
xor bh,bh
mov ah,0eh
mov al,char
mov bl,1h
int 10H
pop dx
pop cx
pop bx
pop ax
endm
SET_CURSOR macro pos ;DH,row DL,col
mov ah,02h
xor bh,bh
mov dx,pos
INT 10H
endm
get_cursor macro
mov ah,03h
xor bh,bh
INT 10H
endm
;********************************************************
CODE segment para
assume cs:code, ds:code
;*******************************************************
INT0_clock proc far
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH SI
PUSH DI
PUSH BP
PUSH DS
PUSH ES
STI
jmp START
_OLD_INT1C dd ?
_COUNT dw ?
_head byte 0C9H,16 DUP(0CDH),0BBH
_mid byte 0BAH,16 DUP(20H),0BAH
_foot byte 0C8H,16 DUP(0CDH),0BCH
_color byte 20H
_week_pos EQU 013FH
_date_pos EQU 023FH
_time_pos EQU 033FH
_msg_date byte 'Date: $'
_date_len EQU $-_msg_date-1
_msg_time byte ' Time: ','$'
_time_len EQU $-_msg_time-1
_msg_week byte ' ','$'
_week_len EQU $-_msg_week-1
_msg_clear byte 10h DUP(' '),'$'
_clear_len EQU $-_msg_clear-1
start:
push cs ;important
pop ds
inc _COUNT
cmp _count,18 ;about a second,18.3. 18*60
jb return
mov _count,0
inc _color ;Change color each second
get_cursor ;save cursor postion for recover
push dx
push word ptr _color ;show frame
mov _color,00FH
print_string _head,003EH,18
print_string _mid,013EH,18
print_string _mid,023EH,18
print_string _mid,033EH,18
print_string _foot,043EH,18
pop word ptr _color
print_string _msg_clear,_week_pos,_clear_len ;show week
SET_CURSOR _week_pos+_week_len
call show_week
inc _color
;SET_CURSOR 003cH
print_string _msg_clear,_date_pos,_clear_len ;show date
SET_CURSOR _date_pos+_date_len
call show_date
inc _color
;SET_CURSOR 013fH
print_string _msg_clear,_time_pos,_clear_len ;show time
SET_CURSOR _time_pos+_time_len
call SHOW_TIME
pop dx
SET_CURSOR dx ;recover cursor,you can work again
return:
CLI
POP ES
POP DS
POP BP
POP DI
POP SI
POP DX
POP CX
POP BX
POP AX
IRET
INT0_clock endp
;********************************************************
show_date proc near
print_string _msg_date,_date_pos,_date_len
mov ah,2ah ;取得系统日期
int 21h ;AL星期,CX年,DH月,DL日
xor ah,ah
;call DEAL_NUM ;不在这里显示星期几,0-6
;print_char ' '
mov ax,cx
call DEAL_NUM ;显示year
print_char '-'
xor ah,ah
mov al,dh
call deal_Num ;month
print_char '-'
mov al,dl
call DEAL_NUM ;day
ret
show_date endp
;*******************************************************
SHOW_TIME proc near
print_string _msg_time,_time_pos,_time_len
mov ah,2ch ;取得系统time
INT 21h ;CH:CL hour:minute,DH:DL second:1/100s
xor ah,ah
mov al,ch
call DEAL_NUM
print_char ':'
mov al,cl
call DEAL_NUM
print_char ':'
mov al,dh
call DEAL_NUM
RET
SHOW_TIME ENDP
;*******************************************************
DEAL_NUM PROC NEAR ;将一个字转换成十进制并输出子程序
push ax
push bx
push cx
push dx
push di
jmp goon
_count_buffer byte 5 DUP(0),'$'
goon:
MOV CX,5
MOV BX,10
MOV DI,OFFSET _count_buffer+4 ;从后往前保存
next:
XOR DX,DX ;将DX清零
DIV BX
OR DL,30H ;也可用ADD DL,30H
MOV BYTE PTR [DI],DL ;将16进制的数转换到ASCII中对应的数,0的ASCII码为 30H (48D)
CMP AX,0
JZ PRINT ;当商为0时,直接去打印,可不打印高位的0.
DEC DI
LOOP next
PRINT:
;MOV DX,DI ;从DI开始打印,因为RESULT不一定够5位
;MOV AH,9
;INT 21H ;调用DOS的21号中断的9号功能,将DB输出
cmp cx,5
jne print_one
print_char '0' ;one char,print other zero
print_one:
mov bl,[di]
cmp bl,'$'
je ok
print_char [di] ;print num,use macro print_char
inc di
jmp print_one
ok:
pop di
pop dx
pop cx
pop bx
pop ax
RET
DEAL_NUM ENDP
;********************************************************
show_week proc near ;show week proc
jmp START
_msg_sun byte 'Sunday','$'
_msg_mon byte 'Monday','$'
_msg_tues byte 'Tuesday','$'
_msg_wed byte 'Wednesday','$'
_msg_thurs byte 'Thursday','$'
_msg_fri byte 'Friday','$'
_msg_sat byte 'Saturday','$'
start:
print_string _msg_week,_week_pos,_week_len
mov ah,2ah ;取得系统日期
int 21h ;AL星期,CX年,DH月,DL日
cmp al,0
je sun
cmp al,1
je mon
cmp al,2
je tues
cmp al,3
je wed
cmp al,4
je thurs
cmp al,5
je fri
cmp al,6
je sat
sun:
print_string _msg_sun,_week_pos+_week_len,6
jmp ok
mon:
print_string _msg_mon,_week_pos+_week_len,6
jmp ok
tues:
print_string _msg_tues,_week_pos+_week_len,7
jmp ok
wed:
print_string _msg_wed,_week_pos+_week_len,9
jmp ok
thurs:
print_string _msg_thurs,_week_pos+_week_len,8
jmp ok
fri:
print_string _msg_fri,_week_pos+_week_len,6
jmp ok
sat:
print_string _msg_sat,_week_pos+_week_len,8
ok:
ret
show_week endp
;*********************************************************
_Head_LEN EQU $-INT0_clock
;********************************************************
main proc far ;TSR important part info
mov ax,cs
mov ds,ax
MOV _COUNT,0
mov ah,35h
mov al,1ch
INT 21H
mov word ptr _OLD_INT1C,bx
mov word ptr _OLD_INT1C+2,es
mov ah,25h
mov al,1ch
mov dx,offset INT0_clock
INT 21H
mov dx,(_Head_LEN+15)/16+10H ;is sloid
MOV AX,3100H
INT 21H
main endp
;******************************************************
code ends
end main
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -