📄 高度精简的万年历程序.txt
字号:
真正的万年历: 90 bytes 的 51 ASM
;==SUB_WNL=== 万年历 ==* Deng Miao * 2004-05-27 ***** GuangZhou ******
SJ DATA 30H ; 世纪 BCD 00 TO 99
NH DATA 31H ; 年号 BCD 00 TO 99 0000 TO 9999 年
YF DATA 32H ; 月份 BCD 01 TO 12
org 000h
MOV SP, #40H
MOV SJ, #20H ;2004-05
MOV NH, #04H
MOV YF, #05H
ACALL SUB_WNL
SJMP $
;===============SUB_WNL===================
; 入口:
; SJ DATA 30H ; 世纪 BCD 00 TO 99
; NH DATA 31H ; 年号 BCD 00 TO 99 0000 TO 9999 年
; YF DATA 32H ; 月份 BCD 01 TO 12
; 出口
; ACC -- 本月天数 BCD 28 to 31
; B -- 本月1日的星期数 1 to 6 == 星期1 to 星期6
; 0 -- 星期日
; 使用 ACC, B, R5,R6
; STACK: 3 bytes (不包括调用)
ORG 50H
; SJ/4 400年大周期
; DateDiff("d", #1/1/2000#, #1/1/2400#)
; =146097天 = 7 * 20871 + 0 天
; 100年 = 7 * 5217 + 6
; 200年 = 7 * 10435 + 4
; 300年 = 7 * 15653 + 2
;
SUB_WNL:
PUSH PSW
MOV A, SJ
ACALL BCD2BIN_DIV4
CPL A
INC A
ANL A, #03H
RL A
MOV R5, A ; R5: 星期 0/6/4/2
MOV A, NH
JZ WNL_1
ACALL BCD2BIN_DIV4
WNL_1:
MOV A, YF
ADD A, #(WNL_TAB-$-4)
MOVC A, @A+PC
MOV R6, A
SWAP A
ACALL WNL_F0
ADDC A, R5
;ADD A, #6; 0000-01-01 星期 6
MOV B, #7
DIV AB
MOV A, R6
ACALL WNL_F0
ADDC A, #28
POP PSW
RET
WNL_TAB:
DB 3*2 + 6 * 32+0 ;1
DB 0*2+1 + 2 * 32+0 ;2
DB 3*2 + 2 * 32+16 ;3
DB 2*2 + 5 * 32+16 ;4
DB 3*2 + 0 * 32+16 ;5
DB 2*2 + 3 * 32+16 ;6
DB 3*2 + 5 * 32+16 ;7
DB 3*2 + 1 * 32+16 ;8
DB 2*2 + 3 * 32+16 ;9
WNL_F0: ; 6 BYTES ;
RRC A ;0AH
ANL A, #07H ;0BH
;0CH
ANL C, F0 ;0DH
;0EH
RET ;0FH
DB 3*2 + 5 * 32+16 ;10H
DB 2*2 + 1 * 32+16 ;11H
DB 3*2 + 3 * 32+16 ;12H
BCD2BIN_DIV4:
MOV R6, A
ANL A, #0F0H
SWAP A
MOV B, #(256-6)
MUL AB
ADD A, R6
MOV B, #4
DIV AB
MOV R6, B
;-------------------------------------
MOV B, #5 ; 3 * 365 + 366 = 7*208 + 5
MUL AB
ADD A, R6 ; 366 = 7*52 + 2
; 366 + 365 = 7*104 + 3
; 366 + 365 + 365 = 7*156+4
MOV C, F0
ADDC A, R5
MOV R5, A
MOV A, R6
JNZ WNL_EXT
DEC R5
SETB C
WNL_EXT:
MOV F0, C
RET
;-----------------------------
END ;======== END OF FILE
本程序来自21ic网友dengm
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -