计算农历的函数汇编原码(1)/zz/

;>>>>>>>>>>>农历计算函数原代码<<<<<<<<<<<<<<<<<
;=============检测阳历对应年份是否闰年==========
;       输入:年份
;       输出:eax = 1 是闰年,否则 eax = 0
_IsLeapYear proto dwYear:dword
;=============取阳历对应年月的天数==============
;       输入:年份,月份
;       输出:eax = 天数
_GetMonthDays proto dwYear:dword,dwMonth:dword
;=============取阳历对应星期几==================
;       输入:年份,月份,日
;       输出:eax=星期,星期日=0,星期一=1…
_GetWeekDay proto dwYear:dword,dwMonth:dword,dwDay:dword
;=============取对应阳历月的节气日==============
;       输入:年份,月份
;       输出:al =第一节气日,ah =第二节气日
_sTermOff proto dwYear:dword,dwMonth:dword
;=============取对应阳历日期的节气序号==========
;       输入:年份,月份,日
;       输出:eax=节气序号,小寒=1,大寒=2…
_GetHolDay proto dwYear:dword,dwMonth:dword,dwDay:dword
;=103f============取两个阳历日期之间的天数==========
;       输入:年份1,月份1,日1,年份2,月份2,日2(第一个为被减数)
;       输出:天数


_GetBetweenDays proto dwYear1:dword,dwMonth1:dword,dwDay1:dword,dwYear2:dword,dwMonth2:dword,dwDay2:dword
;=============取农历年的天数====================
;       输入:年份
;       输出:天数
_GetLunarYearDays proto dwYear:dword
;=============取农历月的天数====================
;       输入:年份,月份
;       输出:天数
_GetLunarMonthDays proto dwYear:dword,dwMonth:dword
;=============填充农历数据结构==================
;       输入:农历数据结构指针(其中阳历必须已填好)
_GetLunarData proto _lpstLunarData:dword
;=============取农历月日字符串==================
;       输入:已填充好农历数据结构指针
;       输出:字符串缓冲区指针(最少13字节)
_GetLunarStr proto _lpstLunarData:dword,lpBuffer:dword
;=============干支序号转换成字符==================
;       输入:干支序号
;       输出:eax=字符
_GetGzStr proto GzNumber:dword
;=============干支序号转换五行生肖==============
;       输入:干支序号
;       输出:eax=低16位生肖,高16位五行
_GetSxStr proto GzNumber:dword
;=============节气序号转换字符=================
;       输入:节气序号
;       输出:eax=节气序号字符
_GetHDStr proto HdNumber:dword
;**************************************************
LUNARDATA       struct
dwYear          dw      ?       ;输入参数 – 年,十进制,例如 2000
dwMonth         dw      ?       ;输入参数 – 月,十进制,例如 10
dwDay           dw      ?       ;输入参数 – 日,十进制,例如 1

dwLunarYear     dw      ?               ;农历年,如 2000
dbLunarMonth    db      ?               ;农历月,如 12
dbLunarDay      db      ?               ;农历日,如 31
dbWeekDay       db      ?               ;星期,星期日=0,星期一=1…
dbIsLeapMonth   db      ?               ;是否是闰月,返回 1 为农历闰月

noLunarYear     db      ?               ;干支年,甲子=0,乙丑=1…
noLunarMonth    db      ?               ;干支月,甲子=0,乙丑=1…
noLunarDay&nbs103fp;     db      ?               ;干支日,甲子=0,乙丑=1…
noLunarHolDay   db      ?               ;农历节气,小寒=1,大寒=2
LUNARDATA       ends
;**************************************************
.code
LunarInfo       dw      04bd8h,04ae0h,0a570h,054d5h,0d260h,0d950h,06554h,056a0h,09ad0h,055d2h
dw      04ae0h,0a5b6h,0a4d0h,0d250h,0d255h,0b540h,0d6a0h,0ada2h,095b0h,04977h
dw      04970h,0a4b0h,0b4b5h,06a50h,06d40h,0ab54h,02b60h,09570h,052f2h,04970h
dw      06566h,0d4a0h,0ea50h,06e95h,05ad0h,02b60h,086e3h,092e0h,0c8d7h,0c950h
dw      0d4a0h,0d8a6h,0b550h,056a0h,0a5b4h,025d0h,092d0h,0d2b2h,0a950h,0b557h
dw      06ca0h,0b550h,05355h,04da0h,0a5d0h,04573h,052d0h,0a9a8h,0e950h,06aa0h
dw      0aea6h,0ab50h,04b60h,0aae4h,0a570h,05260h,0f263h,0d950h,05b57h,056a0h
dw      096d0h,04dd5h,04ad0h,0a4d0h,0d4d4h,0d250h,0d558h,0b540h,0b5a0h,095a6h
dw      095b0h,049b0h,0a974h,0a4b0h,0b27ah,06a50h,06d40h,0af46h,0ab60h,09570h
dw      04af5h,04970h,064b0h,074a3h,0ea50h,06b58h,055c0h,0ab60h,096d5h,092e0h
dw      0c960h,0d954h,0d4a0h,0da50h,07552h,056a0h,0abb7h,025d0h,092d0h,0cab5h
dw      0a950h,0b4a0h,0baa4h,0ad50h,055d9h,04ba0h,0a5b0h,05176h,052b0h,0a930h
dw      07954h,06aa0h,0ad50h,05b52h,04b60h,0a6e6h,0a4e0h,0d260h,0ea65h,0d530h
dw      05aa0h,076a3h,096d0h,04bd7h,04ad0h,0a4d0h,0d0b6h,0d250h,0d520h,0dd45h
dw      0b5a0h,056d0h,055b2h,049b0h,0a577h,0a4b0h,0aa50h,0b255h,06d20h,0ada0h
dw      04b63h
leapBigTab      db      00000010b,00000010b,00010000b,01000000b,00001010b
db      01001000b,00001001b,00000000b,00000000b,00000001b
&nbs103fp; db      00000000b,00000000b,00000000b,00000000b,00000100b
db      00000000b,00000000b,10000000b,00010010b
;=============检测对应年份是否闰年=============
;       输入:年份
;       输出:eax = 1 是闰年,否则 eax = 0
_IsLeapYear     proc dwYear:dword
xor     eax,eax
pushad
mov     ebx,dwYear
mov     eax,ebx
xor     edx,edx
mov     ecx,400
div     ecx
or      edx,edx
je      loc002
mov     eax,ebx
xor     edx,edx
mov     ecx,100
div     ecx
or      edx,edx
je      loc001
mov     eax,ebx
xor     edx,edx
mov     ecx,4
div     ecx
&n103fbsp;       or      edx, edx
jne     loc001
loc002:                 inc     dword ptr [esp+1Ch]             ;returnEAX
loc001:                 popad
ret
_IsLeapYear     endp
;==============取对应阳历年月的天数============
;       输入:年份,月份
;       输出:eax = 天数
_GetMonthDays   proc dwYear:dword,dwMonth:dword
mov     ah,byte ptr dwMonth
cmp     ah,8
setnc   al
add     al,ah                   ;1~12月得数:(1),2,(3),4,(5),6,(7),(9),10,(11),12,(13)
and     al,1
add     al,30
cmp     ah,2
jne     l01
invoke  _IsLeapYear,dwYear
add     al,28
l01:                    movzx   eax,al
ret
_GetMonthDays   endp
;==================================
_GetWeekDay             proc dwYear:dword,dwMonth:dword,dwDay:dword
pushad
movzx   esi,word ptr dwYear
mov     bh,byte ptr dwMonth
&nbsp103f;                      mov     bl,byte ptr dwDay
dec     esi
mov     edi,esi                 ;每年加1天(365/7余数是1)
cmp     bh,3                    ;以下计算闰年数
cmc
adc     esi,0                   ;2月份之前不含本年
mov     eax,esi
shr     eax,2
add     edi,eax                 ;每4年一闰
mov     eax,esi
xor     edx,edx
mov     ecx,100
div     ecx
sub     edi,eax                 ;被100整除不闰
mov     eax,esi
xor     edx,edx
mov     ecx,400
div     ecx
add     edi,eax           &nbs103fp;     ;被400整除还是要闰
movzx   eax,bh                  ;以下计算前一月到年头的天数
dec     al
shl     eax,1
add     edi,eax                 ;每月先以30计算(30/7余数是2)
cmp     bh,8
setnc   al
add     al,bh                   ;1~12月得数:(1),2,(3),4,(5),6,(7),(9),10,(11),12,(13)
shr     al,1                    ;1~12月得数:(0),1,(1),2,(2),3,(3),(4),5,(5),6,(6)
add     edi,eax                 ;大月天数
cmp     bh,3
setnc   al
shl     al,1
sub     edi,eax                 ;平月减二
mov     al,bl
add     eax,edi                 ;日数
xor     edx,edx
mov     ecx,7
&nb103fsp;           div     ecx
mov     dword ptr [esp+1Ch],edx         ;returnEAX
popad
ret
_GetWeekDay             endp