Procedure Rang du jour vers date en ASM DayNumToMD

Pour discuter de l'assembleur
Mesa
Messages : 1092
Inscription : mer. 14/sept./2011 16:59

Procedure Rang du jour vers date en ASM DayNumToMD

Message par Mesa »

Code : Tout sélectionner

; DWORD DayNumToMD(DWORD n, DWORD LeapYearFlag, DWORD* M, DWORD* D)
;
; This function converts the ordinal number of the day in the year to the adequate month and day numbers. 
; The result strongly depends on the flag determining if the year is leap.
;
; Parameters:
;	n - number of the day in the year,
;	LeapYearFlag - flag determining if the year is leap (0 - normal year, 1 - leap year),
;	M - pointer to variable where the calculated month number will be stored,
;	D - pointer to variable where the calculated day number will be stored. 
;
; Returned values:
;	* 0 for the valid parameters (n, LeapYearFlag),
;	* -1 in opposite case.

Procedure.l DayNumToMD(n.l, LeapYearFlag.l, M.l, D.l) 
  Protected tmp.l
  
  EnableASM
  checkparameters:
  TEST	LeapYearFlag, -2	; 0 <= LeapYearFlag <= 1
  JNZ	l_daynumtomd_error
  
  CMP	n, 1						    ; n >= 1
  JB	l_daynumtomd_error						
  
  MOV	eax, 365					
  ADD	eax, LeapYearFlag	; eax := 365 + LeapYearFlag
  CMP	n, eax					  ; n <= eax
  JA	l_daynumtomd_error						
  
  calculatemd:
  MOV	eax, LeapYearFlag	; ebx := LeapYearFlag
  LEA	eax, [eax + 2*eax]; ebx := 3*ebx = 3*LeapYearFlag
  SHL	eax, 3						; ebx := 8*ebx = 24*LeapYearFlag
  
  MOV tmp, eax			    ; Sauvegarde de 24*LeapYearFlag dans tmp
  
  MOV	ecx, 12						;
  
  lloop:							  ; ecx := max{i; 1 <= i <= 12, DaySum(i, LeapYearFlag) < n} = m
  LEA eax,[daysum]	
  DEC eax
  DEC eax
  ADD eax, tmp
  ADD eax, ecx 
  ADD eax, ecx 
  MOVZX	edx, word [eax];MOVZX	edx, [DaySum - 2 + ebx + 2*ecx]		
  
  CMP	n, edx				   ; edx := DaySum(m, LeapYearFlag)
  JA	l_daynumtomd_loopend				
  LOOP	l_daynumtomd_lloop					
  
  loopend:
  MOV	eax, M				  ; M := ecx = m
  MOV	[eax], ecx				
  
  MOV	ecx, n				  ; ecx := n
  SUB	ecx, edx			  ; ecx := ecx - edx = n - DaySum(m, LeapYearFlag)
  
  MOV	eax, D				  ; D := ecx
  MOV	[eax], ecx				
  
  XOR	eax, eax
  
  JMP	l_daynumtomd_theend
  
  error:
  MOV	eax, -1
  
  theend:
   
  DisableASM
  
  ProcedureReturn 
  !daysum: 
  !DW  0,  31,  59,  90, 120, 151, 181, 212, 243, 273, 304, 334  
  !DW  0,  31,  60,  91, 121, 152, 182, 213, 244, 274, 305, 335 
EndProcedure


; Il faut déclarer 2 variables (2 façons de faire)
; D=0
; M=0
Define.l  D, M

Debug DayNumToMD(1, 0, @M, @D) ;n, LeapYearFlag, M, D
Debug D
Debug M
Debug DayNumToMD(60, 0, @M, @D) ;n, LeapYearFlag, M, D
Debug D
Debug M
Debug DayNumToMD(60, 1, @M, @D) ;n, LeapYearFlag, M, D
Debug D
Debug M
Debug DayNumToMD(365, 0, @M, @D) ;n, LeapYearFlag, M, D
Debug D
Debug M
Debug DayNumToMD(366, 1, @M, @D) ;n, LeapYearFlag, M, D
Debug D
Debug M
Mesa.