⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cal.asm

📁 汇编所写的日历程序源代码
💻 ASM
📖 第 1 页 / 共 2 页
字号:
mov ax,w [julian_lo]
mov cl,07
div cx                                 ; divide julian date by seven
mov al,01                              ; to get day of the week.
sub al,dl
ret                                    ; and return offset in .al

print_cal:                             ; print a calendar:
call crlf                              ; blank line
inc b [flags]                          ; full-year calendar?
je print_year_cal                      ; if so, go do that
call header_out                        ; display month and year
call crlf                              ; end of line
dosprint msg_cal1                      ; print days-of-week line
call crlf                              ; end of line
mov si,0006                            ; print six rows of dates :
call compute_julian                    ; calculate offset for start of month
mov ch,al
l4:
call print_cal_line                    ; print a row of dates
call crlf                              ; and terminate print line
add ch,07                              ; add seven to date offset
dec si                                 ; done six rows yet?
jne l4                                 ; if not, loop back
ret                                    ; if so, exit

print_year_cal:                        ; print full-year calendar:
zero si                                ; start in the first column
l0:
call header_out                        ; display month and year
mov cx,0009
call spaces_out
call compute_julian                    ; compute values for first of month
mov b [cal1+si],al                     ; save in temp variable
inc w [month]                          ; move on to next month
inc si                                 ; and next column
cmp si,0003                            ; printed three month names yet?
jne l0                                 ; no, loop back for more
call crlf                              ; yes, end print line
l2:
dosprint msg_cal1                      ; print days-of-week line
dec si                                 ; three times
jne l2
call crlf                              ; then end print line
sub w [month],0003                     ; back to first-column month
mov si,0006                            ; print six rows of dates
l5:
zero di                                ; start in first column
l6:
mov ch,b [cal1+di]                     ; get offset for start of month
call print_cal_line                    ; print a row of dates
add b [cal1+di],07                     ; then add seven to date offset
inc w [month]                          ; move on to the next month
inc di                                 ; in the next column
cmp di,0003                            ; done three columns yet?
jb l6                                  ; no, loop back and do next column
call crlf                              ; terminate print line
sub w [month],0003                     ; back to first-column month
dec si                                 ; printed six rows yet
jne l5                                 ; no, loop back for more
call crlf                              ; print a blank line
add w [month],03                       ; move ahead to next row of months
#if !no_pause
cmp w [month],0007                     ; does july come next?
jne > l7                               ; if not, no need to pause
mov bx,0001                            ; handle for stdout --
doscall2 4400                          ; ioctl get device data
and dl,82                              ; examine device and stdout bits
cmp dl,82                              ; standard output to the console?
jne > l7                               ; if not, do not pause
dosprint msg_more                      ; time to pause:  print pause message
l65:
mov ah,01                              ; keyboard:  check key buffer status
int 16
pushf                                  ; save status
mov ah,00                              ; keyboard:  get key
int 16
popf                                   ; are we flushing the key buffer?
jne l65                                ; if so, loop back for more
l7:
#endif
cmp w [month],000c                     ; all done yet?
ja ret                                 ; yes, exit
jmp print_year_cal                     ; no, loop back for next three months

print_cal_line:                        ; print row of dates:
mov cl,00                              ; start in first day-of-week column
l2:
mov al,ch                              ; get date offset from .ch
add al,cl                              ; and add the column number
call out2dig                           ; print number if valid
inc cl                                 ; next day-of-week column
cmp cl,07                              ; done seven yet?
jne l2                                 ; nope, keep going
call space_out
int 21                                 ; yes, print two more trailing spaces
ret                                    ; and exit

out2dig:                               ; print date in .al, if it is valid:
cmp al,00                              ; zero?
je > l1                                ; if so, not valid; print spaces
mov bx,w [month]                       ; get offset into month-lengths table
cmp al,b [months_table-1+bx]           ; date value too large?
jbe > l2                               ; no, print it
l1:                                    ; invalid date value:
mov dx,offset msg_3sp                  ; print three spaces
l15:
doscall 09
ret                                    ; and exit
l2:                                    ; valid date value:
#if !no_splat
cmp al,b [today]                       ; is this today's date ?
jne > l3                               ; if not, continue
mov dx,offset msg_today                ; if so, print an asterisk and exit
jmp l15
#endif
l3:
cmp al,0a                              ; ten or greater?  i.e., two digits?
jae > l4                               ; yes, print two digits
push ax                                ; otherwise, save value
call space_out                         ; print a space
pop dx
add dl,'0'                             ; convert one-digit value to ascii
int 21                                 ; and print it
jmp short space_out                    ; print trailing space and exit
l4:                                    ; print two-digit value:
call bcdout                            ; then print a space and exit

space_out:                             ; print a space:
mov dl,20                              ; ascii value of a space
doscall 02                             ; print it
ret

header_out:                            ; display month and year :
call six_spaces                        ; print six spaces
mov ax,w [month]                       ; get month number
mov cl,03
mul cl                                 ; and multiply by three
mov bx,ax                              ; to get pointer to month name
mov ah,02                              ; dos print-a-character function
l0:                                    ; print three characters
mov dl,b [month_names-3+bx]            ; get byte from month name
int 21                                 ; and print it
inc bx                                 ; advance pointer
loop l0                                ; and continue until done
call space_out                         ; print one space
mov ax,w [year]                        ; get the current year
mov cl,0100xd
div cl                                 ; divide year by 100
mov bl,ah                              ; save the remainder
call bcdout                            ; print the century
mov al,bl                              ; get the remainder and fall through -
bcdout:                                ; print value in .al
aam                                    ; unpack decimal digits
add ax,'0' by '0'                      ; and convert to ascii digits
push ax                                ; save the remainder
mov dl,ah
doscall 02                             ; print the tens digit
pop dx                                 ; get the ones digit
int 21                                 ; print the ones digit
ret

crlf:                                  ; terminate print line:
dosprint msg_crlf                      ; print carriage return and line feed
ret

six_spaces:                            ; print six spaces :
mov cx,0006                            ; load .cx with six and fall through

spaces_out:                            ; print .cx number of spaces:
mov ah,02                              ; dos print-a-character function
mov dl,20                              ; ascii value of a space
l0:
int 21                                 ; print it
loop l0                                ; however many times
ret


flags:                                 ; nonzero means full-year calendar
db 00


months_table:                          ; number of days in each month
db 1f, 1c, 1f, 1e, 1f, 1e, 1f, 1f, 1e, 1f, 1e, 1f

month_names:                           ; three-letter month names
db 'JanFebMarAprMayJunJulAugSepOctNovDec'

msg_syntax:
db 0d,0a
db 'CAL  1.07  Freeware',0d,0a
db 'Copyright 1998, Charles Dye',0d,0a
db 0a
db 'CAL',0d,0a
db 'CAL mm/yyyy',0d,0a
db 'CAL yyyy'

msg_crlf:
db 0d,0a,'$'

msg_year_bad:
db 0d,0a,'Year is 1753-2399!',0d,0a,'$'

msg_month_bad:
db 0d,0a,'Month is 1-12!',0d,0a,'$'

msg_cal1:
#if monday
db 'Mo Tu We Th Fr Sa Su'
#else
db 'Su Mo Tu We Th Fr Sa'
#endif

msg_3sp:
db '   $'

#if !no_pause
msg_more:
db 'More',0d,'$'
#endif

#if !no_splat
msg_today:
db ' * $'
#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -