This file can be included to program for Windows or Linux written in EuroAssembler.
It declares the most often used constant symbols and structures used for time and date functions.
time HEAD
FILETIME STRUC .dwLowDateTime D DWORD .dwHighDateTime D DWORD ENDSTRUC FILETIME
TimeSpec DS TIMESPEC, .tv_sec=3, tv_nsec=200_000_000
LinABI nanosleep, TimeSpec, 0 ; Sleep for 3.2 seconds.TIMESPEC STRUC .tv_sec D QWORD ; Seconds. .tv_nsec D QWORD ; Nanoseconds (0..999_999_999). ENDSTRUC TIMESPEC
SYSTEMTIME STRUC .wYear D WORD .wMonth D WORD ; 1..12 .wDayOfWeek D WORD ; 0=Sunday, 1=Monday etc. .wDay D WORD ; 1..31 .wHour D WORD ; 0..23 .wMinute D WORD ; 0..59 .wSecond D WORD ; 0..59 .wMilliseconds D WORD ; 0..999 ENDSTRUC SYSTEMTIME
Time2SystemTime %MACRO aSystemTime, TZ=0
%IF %^WIDTH=64
PUSHQ %TZ
PUSH %aSystemTime
%ELSE
PUSHD %TZ
PUSH %aSystemTime
%ENDIF
CALL Time2SystemTime@RT:
Time2SystemTime@RT: PROC1
%IF %^WIDTH=64
PUSH RAX,RBX,RCX,RDX,RSI,RDI,RBP
MOV RBX,[RSP+9*8] ; %TZ
MOV RDI,[RSP+8*8] ; %aSystemTime
%ELSE
PUSH EAX,EBX,ECX,EDX,ESI,EDI,EBP
MOV EBX,[ESP+9*4] ; %TZ
MOV EDI,[ESP+8*4] ; %aSystemTime
%ENDIF
ADD EAX,EBX
MOV EBX,EAX
MOV ECX,7*86400
ADD EAX,4*86400 ; Compute day of the week.
XOR EDX,EDX
%IF %^WIDTH=64
DIV RCX
%ELSE
DIV ECX
%ENDIF
MOV EAX,EDX
MOV ECX,86400
XOR EDX,EDX
%IF %^WIDTH=64
DIV RCX
%ELSE
DIV ECX
%ENDIF
MOV EBP,EAX ; Save the day of the week.
MOV EAX,EBX ; Restore the number of seconds.
MOV ECX,365*86400 ; Seconds in a nonleap year.
MOV EDX,366*86400 ; Seconds in a leap year.
MOV EBX,1970 ; 1970.
.10: SUB EAX,ECX
JB .25:
INC EBX ; 1971,1975,1979,1983,1987,1991,1995,1999,2003,2007,2011,2015,2019,2023,2027,2031,,
SUB EAX,ECX
JB .25:
INC EBX ; 1972,1976,1980,1984,1988,1992,1996,2000,2004,2008,2012,2016,2020,2024,2028,2032,,
SUB EAX,EDX
JB .20:
INC EBX ; 1973,1977,1981,1985,1989,1993,1997,2001,2005,2009,2013,2017,2021,2025,2029,2033,,
SUB EAX,ECX
JB .25:
INC EBX ; 1974,1978,1982,1986,1990,1994,1998,2002,2006,2010,2014,2018,2022,2026,2030,2034,,
JMPS .10:
.20: ADD EAX,EDX
JMPS .30:
.25: ADD EAX,ECX
.30: XCHG EBX,EAX
STOSW ; Year is computed in BX.
XCHG EBX,EAX
MOV ECX,31*86400 ; Days in a long month.
MOV EDX,30*86400 ; Days in a short month.
MOV ESI,28*86400 ; Days in February in a nonleap year.
TEST BL,3
JNZ .35:
ADD ESI,86400 ; Days in February in a leap year.
.35: MOV EBX,1 ; January.
.40: SUB EAX,ECX
JB .60:
INC EBX ; February.
SUB EAX,ESI
JB .55:
INC EBX ; March.
SUB EAX,ECX
JB .60:
INC EBX ; April.
SUB EAX,EDX
JB .50:
INC EBX ; May.
SUB EAX,ECX
JB .60:
INC EBX ; June.
SUB EAX,EDX
JB .50:
INC EBX ; July.
SUB EAX,ECX
JB .60:
INC EBX ; August.
SUB EAX,ECX
JB .60:
INC EBX ; September.
SUB EAX,EDX
JB .50:
INC EBX ; October.
SUB EAX,ECX
JB .60:
INC EBX ; November.
SUB EAX,EDX
JB .50:
INC EBX ; December.
SUB EAX,ECX
JB .60:
JMP .65:
.50: ADD EAX,EDX
JMP .65:
.55: ADD EAX,ESI
JMP .65:
.60: ADD EAX,ECX
.65: XCHG EBX,EAX ; Month is computed in BX (1..12).
STOSW
XCHG EAX,EBP ; Restore the day of the week.
STOSW
XCHG EAX,EBX ; Restore the rest to RAX.
MOV ECX,86400 ; Seconds in a day.
XOR EDX,EDX
%IF %^WIDTH=64
DIV RCX
%ELSE
DIV ECX
%ENDIF
INC EAX
STOSW ; Day in the month.
MOV EAX,EDX
MOV ECX,3600 ; Seconds in an hour.
XOR EDX,EDX
%IF %^WIDTH=64
DIV RCX
%ELSE
DIV ECX
%ENDIF
STOSW ; Hour.
MOV EAX,EDX
MOV ECX,60 ; Second in a minute.
XOR EDX,EDX
%IF %^WIDTH
DIV RCX
%ELSE
DIV ECX
%ENDIF
STOSW ; Minute.
MOV EAX,EDX
STOSW ; Second.
XOR EAX,EAX
STOSW ; Miliseconds are not supported.
%IF %^WIDTH=64
POP RBP,RDI,RSI,RDX,RCX,RBX,RAX
RET 2*8
%ELSE
POP EBP,EDI,ESI,EDX,ECX,EBX,EAX
RET 2*4
%ENDIF
ENDPROC1 Time2SystemTime@RT
%ENDMACRO Time2SystemTime
Macro Time1970 converts in 64bit Linux or Windows the time from 32bit C-time (number of seconds since
midnight Jan 1st 1970 UTC to the ASCIIZ format yyyy/mm/dd hh:mm:ss.
yyyy/mm/dd hh:mm:ss, zero-terminated.cpuext64.htm.
Time1970 %MACRO DateTime32, DateTimeString
PUSH %DateTimeString, %DateTime32
CALL Time1970@RT
Time1970@RT PROC1
PUSH RAX,RBX,RCX,RDX,RSI,RDI
SUB RSP,16
%month %SETA 0
DaysInMonth %FOR 31,28,31,30,31,30,31,31,30,31,30,31
MOVB [RSP+%month],%DaysInMonth
%month %SETA %month+1
%ENDFOR DaysInMonth
MOV RDI,[RSP+10*8] ; %DateTimeString
MOV RAX,[RSP+ 9*8] ; %DateTime32
XOR EDX,EDX
MOV ECX,24*60*60
DIV RCX
; RAX is whole days since Jan 1st 1970. RDX is seconds since midnight.
MOV RSI,RDX
MOV ECX,365+365+366+365
XOR EDX,EDX
DIV RCX
LEA RBX,[4*RAX+1970] ; RBX is four-year. EDX is number of days since RBX (0..4*365)
SUB EDX,365
JB .30:
INC EBX
SUB EDX,365
JB .30:
INC EBX
SUB EDX,366
JB .20:
INC EBX
JMPS .40:
.20: INC EDX
.30: ADD EDX,365
.40: TEST BL,3 ; RBX is year. EDX is number of days since RBX (0..365)
JNZ .50:
MOVB [RSP+1],29
.50: MOV EAX,EBX
StoD RDI,Size=4
MOV AL,'/'
STOSB
XOR EBX,EBX
XOR ECX,ECX
.60: MOVZXB EAX,[RSP+RBX] ; 31,28|29,31,30,,,
ADD ECX,EAX ; 31,59|60,90|91,,,
INC EBX ; RBX is month (1..12).
CMP ECX,EDX
JNA .60:
SUB ECX,EAX
SUB EDX,ECX
INC EDX ; RBX is month, RDX is day (1..31).
MOV EAX,EBX
StoD RDI,Size=2,Align=right,LeadingZeroes=yes ; Store month.
MOV AL,'/'
STOSB
MOV EAX,EDX
StoD RDI,Size=2,Align=right,LeadingZeroes=yes ; Store days.
MOV AL,' '
STOSB
MOV EAX,ESI ; EAX is seconds since midnight.
XOR EDX,EDX
MOV ECX,60*60
DIV RCX
StoD RDI,Size=2,Align=right,LeadingZeroes=yes ; Store hours.
MOV AL,':'
STOSB
MOV EAX,EDX
XOR EDX,EDX
MOV ECX,60
DIV RCX
StoD RDI,Size=2,Align=right,LeadingZeroes=yes ; Store minutes.
MOV AL,':'
STOSB
MOV EAX,EDX
StoD RDI,Size=2,Align=right,LeadingZeroes=yes ; Store seconds.
XOR EAX,EAX
STOSB
ADD RSP,16
POP RDI,RSI,RDX,RCX,RBX,RAX
RET 2*8
ENDP1 Time1970@RT
%ENDMACRO Time1970
ENDHEAD string64
ENDHEAD time