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

;===============================================
HgnMs           dq      31556925.9747   ;每回归年秒数
OneDay          dd      86400           ;每天秒数
sTermInfo       dw      0,0,51,212,505,974,1619,2465,3485,4679,5992,7405,8847,10285,\
11651,12913,14022,14958,15703,16258,16635,16856,16956,16974
_sTermOff       proc    dwYear:dword,dwMonth:dword
local   @Temp1:dword,@Temp2
local   @Rag1:word,@Rag2:word


pushad
xor     eax,eax
mov &103fnbsp;   @Temp1,eax
mov     @Temp2,eax
cmp     dwYear,1900
jb      l002
cmp     dwMonth,12
jae     l002
finit
fstcw   @Rag1
fwait
mov     ax,@Rag1
and     ah,0F3h                 ;清圆整控制
or      ah,8                    ;圆整控制=10(舍入)
mov     @Rag2,ax
fldcw   @Rag2

mov     eax,dwYear
sub     eax,1900
mov     @Temp2,eax
fild    @Temp2
fmul    HgnMs                   ;回归年换算成秒

mov     ebx,dwMonth
shl     ebx,1
mov     eax,21208
&nbsp103f;                    mul     ebx
add     eax,7325                ;5-2″5′
mov     edx,eax
movzx   ecx,sTermInfo[ebx*2]
add     eax,ecx                 ;该月第一个节气距小寒的分数
imul    eax,60
mov     @Temp1,eax
fild    @Temp1
fadd    st,st(1)
fidiv   OneDay
fwait
fistp   @Temp1                  ;输出
;====
mov     eax,edx
add     eax,21208
movzx   ecx,sTermInfo[ebx*2+2]
add     eax,ecx                 ;该月第一个节气距小寒的分数
imul    eax,60
mov     @Temp2,eax
fiadd   @Temp2
fidiv   OneDay
fwait
&nbsp103f;                     fistp   @Temp2                  ;输出
;====
mov     esi,dwYear
dec     esi
mov     edi,esi
imul    edi,365                 ;每年365天
cmp     dwMonth,2
cmc
adc     esi,0
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&nb103fsp;                ;被400整除还是要闰
mov     ah,byte ptr dwMonth
mov     al,ah
inc     al
cmp     ah,2
jb      l001
cmp     ah,7
setnc   al
inc     al
add     al,ah
shr     al,1
dec     al
l001:                   movzx   ebx,al
dec     ebx
mov     al,30
mul     ah
add     bx,ax
add     edi,ebx
sub     edi,693595              ;1900.1.1总天数
fwait
sub     @Temp1,edi
sub     @Temp2,edi
fldcw   @Rag1
l002:             &nbsp103f;     popad
mov     eax,@Temp1
mov     ah,byte ptr @Temp2
ret
_sTermOff       endp
;=======================================
_GetHolDay      proc    dwYear:dword,dwMonth:dword,dwDay:dword
mov     eax,dwMonth
dec     eax
invoke  _sTermOff,dwYear,eax
push    ecx
mov     ecx,eax
xor     eax,eax
cmp     cl,byte ptr dwDay
je      loc01
cmp     ch,byte ptr dwDay
jne     loc02
inc     eax
loc01:                  inc     eax
mov     ecx,dwMonth
dec     ecx
shl     ecx,1
add     eax,ecx
loc02:                  pop     ecx
ret
_GetHolDay      endp
;===================================
_GetBetweenDays         proc    dwYear1:dword,dwMonth1:dword,dwDay1:dword,dwYear2:dword,dwMonth2:d103fword,dwDay2:dword
pushad
movzx   esi,word ptr dwYear1
mov     bh,byte ptr dwMonth1
mov     bl,byte ptr dwDay1
mov     ebp,1
l01:                    dec     esi
mov     edi,esi
imul    edi,365                 ;每年365天
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
&nb103fsp;                       xor     edx,edx
mov     ecx,400
div     ecx
add     edi,eax                 ;被400整除还是要闰
movzx   eax,bh                  ;以下计算前一月到年头的天数
dec     al
imul    eax,30                  ;每月先以30计算
add     edi,eax
cmp     bh,8
setnc   al
mov     ah,0
add     al,bh                   ;1~12月得数:(1),2,(3),4,(5),6,(7),(9),10,(11),12,(13)
shr     al,1
add     edi,eax                 ;加大月天数
cmp     bh,3
setnc   al
shl     al,1
sub     edi,eax                 ;平月减二
mov     al,bl
&n103fbsp;                 add     edi,eax                 ;日数
or      ebp,ebp
jz      l02
mov     [esp+1Ch],edi           ;returnEAX
mov     ebp,[esp+8]
movzx   esi,word ptr dwYear2
mov     bh,byte ptr dwMonth2
mov     bl,byte ptr dwDay2
xor     ebp,ebp
jmp     l01
l02:                    sub     [esp+1Ch],edi           ;returnEAX
popad
ret
_GetBetweenDays         endp