Code : Tout sélectionner
; DWORD IsLeapYear(DWORD Y, DWORD Gregorian)
;
; This function determines if the given year is leap in the chosen calendar.
;
; Parameters:
; Y - year,
; Gregorian - chosen calendar (0 - Julian, 1 - Gregorian).
;
; Returned values:
; * 1 if the year Y is leap, 0 - in opposite case,
; * -1 for the invalid parameters.
;
;proc IsLeapYear, Y, Gregorian
Procedure IsLeapYear(Y, Gregorian)
EnableASM
PUSHFD
PUSH ebx edx
!CheckParameters:
TEST [Gregorian], -2 ; 0 <= Gregorian <= 1
JNZ Error ;
!IsYNegative:
MOV eax, [Y] ; eax := Y
TEST eax, eax
JZ Error
JNS CheckCalendar
; eax < 0 (Y < 0)
;
INC eax ; eax := eax + 1
NEG eax ; eax := -eax = -(Y + 1) = -Y - 1 =
; = |Y| - [Y < 0] = Y'
!CheckCalendar:
CMP [Gregorian], 0
JE mod4
!Gregorian:
XOR edx, edx ; eax := E(eax / 100) = E(Y' / 100)
MOV ebx, 100 ; edx := eax mod 100 = Y' mod 100
DIV ebx ;
TEST edx, edx
JZ mod4
MOV eax, edx ; eax := edx = Y' mod 100
;
; {(Y' mod 100) mod 4 = Y' mod 4}
!mod4:
SHR eax, 1 ; eax := E(eax / 2); CF := eax mod 2
JC Result ;
SHR eax, 1 ; eax := E(eax / 2); CF := eax mod 2
JMP Result ;
!Error:
MOV eax, -1
JMP Endd
!Result:
SETNC al ; eax := not CF
MOVZX eax, al ;
!Endd:
POP edx ebx
POPFD
RET ;ProcedureReturn ? (renvoie eax ?)
DisableASM
EndProcedure
; ok=IsLeapYear(2000, 1)
; Debug ok
; ok=IsLeapYear(2000, 1)
; Debug ok
ça ne compile plus.
Une idée ?
M.