The MASM Forum Archive 2004 to 2012

General Forums => The Workshop => Topic started by: ToutEnMasm on February 19, 2008, 02:22:31 PM

Title: I lose my time . Or CRT times functions
Post by: ToutEnMasm on February 19, 2008, 02:22:31 PM
Hello,
Seeing than many peoples search for times functions, I see this in the CRT library:
http://www.warpspeed.com.au/cgi-bin/inf2html.cmd?..\html\book\IBMVACPP\CPPLIB.INF+24

17 functions not very hard to used,here is a sample:

Quote
   include C:\masm32\sdk\translate.inc
   include C:\masm32\sdk\stdio.sdk
   include C:\masm32\sdk\time.sdk
   includelib C:\PROGRA~1\MICROS~1.0\VC\lib\libcmt.lib   
   includelib C:\PROGRA~1\MICROS~1.0\VC\lib\OLDNAMES.lib
.data
format db "The time is %s",13,10,0
.code
main PROC C un:DWORD,deux:DWORD
   Local ltime:QWORD
   invoke time,addr ltime
   invoke ctime,addr ltime
   mov edx,eax
   invoke printf,addr format, edx
;****************************************************************************
;The output should be similar to:

;The time is Thu Jan 12 11:38:37 1995
;****************************************************************************/
   mov eax,0   
ret
main endp
end






Title: Re: I lose my time . Or CRT times functions
Post by: Vortex on February 19, 2008, 06:41:05 PM
ToutEnMasm,

Using msvcrt.dll, the size of the executable is 1536 bytes :

.386
.model flat, stdcall
option casemap:none

include     \masm32\include\windows.inc
include     \masm32\include\msvcrt.inc
includelib  \masm32\lib\msvcrt.lib

.data
format db "The time is %s",13,10,0

.code

main PROC C un:DWORD,deux:DWORD
    LOCAL   ltime:QWORD
    invoke  crt_time,ADDR ltime
    invoke  crt_ctime,ADDR ltime
    invoke  crt_printf,ADDR format,eax
    xor     eax,eax
    ret
main ENDP
END

[attachment deleted by admin]
Title: Re: I lose my time . Or CRT times functions
Post by: ToutEnMasm on February 19, 2008, 08:00:47 PM
Ok,the msvcrt.lib make many more little files,at the price of dependances with the .....80.dll.
With more code,a manifest is needed

Quote
;ressource
APP_MANIFEST RT_MANIFEST  DISCARDABLE  "Microsoft.VC80.CRT.manifest"
;-------------- content of file  Microsoft.VC80.CRT.manifest   in the directory of the project ------------
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!-- Copyright © 1981-2001 Microsoft Corporation-->
<assembly xmlns="urn:schemas-microsoft-com:asm.v1"
                                 manifestVersion="1.0">
  <noInheritable/>
  <assemblyIdentity
    type="win32"
    name="Microsoft.VC80.CRT"
    version="8.0.50608.0"
    processorArchitecture="x86"
    publicKeyToken="1fc8b3b9a1e18e3b" />
  <file name="msvcr80.dll"/>
  <file name="msvcp80.dll"/>
  <file name="msvcm80.dll"/>
</assembly>
;---------------------------------------------------------------------------------------------------------------------

Title: Re: I lose my time . Or CRT times functions
Post by: Vortex on February 19, 2008, 08:11:27 PM
Hi ToutEnMasm,

You don't need the manifest file because the modified version of your example code above uses msvcrt.lib coming with the Masm32 package :

includelib  \masm32\lib\msvcrt.lib

I prefer to use Hutch's msvcrt.lib instead of another one supporting a higher version of Visual Studio.
Title: Re: I lose my time . Or CRT times functions
Post by: GregL on February 19, 2008, 08:38:22 PM
Quote from: VortexI prefer to use Hutch's msvcrt.lib instead of another one supporting a higher version of Visual Studio.

Yes, I usually use the MASM32 version of msvcrt.lib (and ML and LINK) too.

If you want (have) to use some of the new "features" of Windows XP and Windows Vista, you are forced into using the newer ones.

Title: Re: I lose my time . Or CRT times functions
Post by: ToutEnMasm on February 19, 2008, 08:48:02 PM

The masm lib have been modified and couldn't be mix with the other lib of the SDK,see:
http://www.masm32.com/board/index.php?topic=7996.msg58546#msg58546
That is for that I use the VC++ one.
When functions have a reserved name of masm,this can be solve by linking them dynamically.They are very few like that.
Duplicate name of functions (masm32 and sdk) can be solve by changing the name of the masm one.
I wait for a masm32 lib that is compatible with the SDK,not very difficult to do.

Title: Re: I lose my time . Or CRT times functions
Post by: Vortex on February 19, 2008, 09:11:09 PM
ToutEnMasm,

Could you try this (http://www.masm32.com/board/index.php?topic=1638.msg49345#msg49345) version of msvcrt.lib? It's another approach to solve the conflict with names.
Title: Re: I lose my time . Or CRT times functions
Post by: GregL on February 19, 2008, 09:37:00 PM
Vortex,

Please explain how that msvcrt.lib is different from the one in the MASM32 package?

Title: Re: I lose my time . Or CRT times functions
Post by: ToutEnMasm on February 20, 2008, 08:40:30 AM
Hello,
I have tested the msvcrt.ib of vortex (building the library and create the executable).
This one is build by link -lib option and extract from the dll.
It work.
For greg.
The new library is different in many things
-No entry point,the executable must provide one
-No need of manifest
-Functions are all renamed.
I don't see how link can do that but it made it.

I post a sample that use the normal way,that is VC++ libs.
The code is the one of vortex sample modify to use the vc++(2008) lib





[attachment deleted by admin]
Title: Re: I lose my time . Or CRT times functions
Post by: ToutEnMasm on February 20, 2008, 02:03:27 PM

This demo is not completed without this third way ,the use of the libcmt.lib instead of msvcrt.lib.
Executable is bigger,there is no need of manifest,the code is exactly the same.
You win an executable who need less conditions to work.Try to run the one compiled with msvcrt in the zip,you have this message "..couldn't be initialised".He must be unpacked.
Try the same thing with this one.
The both samples I have posted,can be used with other libraries of the SDK.It isn't the case with the masm32 msvcrt.lib .
Explain:The msvcrt.lib give functions to other libraries in the SDK (ddk,directx,..)




[attachment deleted by admin]
Title: Re: I lose my time . Or CRT times functions
Post by: Vortex on February 20, 2008, 06:47:14 PM
Hi ToutEnMasm,

Thanks for your examples. Would you like to try this (http://www.masm32.com/board/index.php?topic=1638.msg63622#msg63622) new release? The previous version of msvcrt.lib did not contain the conflicting MASM keywords, I fixed it now. My apologies.

Hi Greg,

All the functions in the 2nd linker member table are prefixed with crt_ but all the IMAGE_ARCHIVE_MEMBER_HEADER entries are filled with original C function names so the prefixed names in the object files are "forwarded" to the conventional names by the linker.
Title: Re: I lose my time . Or CRT times functions
Post by: GregL on February 20, 2008, 08:50:32 PM
Vortex,

Sorry if I am being thick, but I thought that's what the masm32 msvcrt.lib does, translates the crt_ prefixed function names to the actual function names.

I guess I have always taken import libraries for granted, is there any good documentation about the inner workings of them.

Title: Re: I lose my time . Or CRT times functions
Post by: Vortex on February 20, 2008, 09:08:36 PM
Hi Greg,

The Microsoft Portable Executable and Common Object File Format Specification (http://www.microsoft.com/whdc/system/platform/firmware/PECOFF.mspx) explains the internals of import libraries.
Title: Re: I lose my time . Or CRT times functions
Post by: GregL on February 20, 2008, 09:29:47 PM
Vortex,

So, you are saying I need to do some reading?  :bg  Thanks for the link.


ToutEnMasm,

Regarding the CRT date and time functions, I posted an example here (http://www.masm32.com/board/index.php?topic=1638.msg12823#msg12823). After assembling and running it today, I found an error and updated it.

Title: Re: I lose my time . Or CRT times functions
Post by: ToutEnMasm on February 21, 2008, 01:47:07 PM
Hi greg,
I have made a rewrite of your code using the windows.sdk
The only change is GetTimeZoneInformation instead of :
Quote
mov eax, crt__tzname
    .if tstruct.dstflag == 0
        mov edx, [eax+0] 
        mov ptzname, edx
    .else
The 'mov eax, crt__tzname' need a real explain and is deprecated.
Quote
invoke printf, chr$(" Days until Christmas:               %.0L",13,10), days

The format  %fl made a runtime error ,change to %.0L

That's all


Quote
    .486
    .model flat, stdcall
    option casemap :none
   include \masm32\sdk\translate.inc
   include \masm32\sdk\windows.sdk
   include \masm32\sdk\stdio.sdk
   include \masm32\sdk\conio.sdk
   include \masm32\sdk\time.sdk
   include \masm32\sdk\timeb.sdk   
   include \masm32\sdk\mapiwin.sdk
   
    includelib C:\PROGRA~1\MICROS~1.0\VC\lib\libcmt.lib   
    includelib C:\PROGRA~1\MICROS~1.0\VC\lib\oldnames.lib
   
    includelib c:\masm32\lib\kernel32.lib
   
    include macro.inc
           
    main PROTO C :DWORD,:DWORD
    maincrt PROTO
    _difftime64 PROTO pTime1:PTR QWORD, pTime2:PTR QWORD, pDiff:PTR REAL8
    WaitKeyCrt PROTO
.data

    align 8
    time1     QWORD     0
    time2     QWORD     0
    diff      REAL8     0.0
    day       REAL8     86400.0  ; 60*60*24
    days      REAL8     0.0
    tstruct   __timeb64 <0>
    align 4
    hmodule   DWORD     0
    pxmas     DWORD     0
    ptzname   DWORD     0
    tmpbuf    BYTE      128 dup(0)
    ampm      BYTE      "AM", 0
    newline   BYTE      13, 10, 0
    tziOld TIME_ZONE_INFORMATION <>
.code

main proc C un:DWORD,deux:DWORD
    invoke maincrt
    invoke WaitKeyCrt
ret
main endp

maincrt  PROC
   Local dwRet:DWORD
   Local timezone[64]:BYTE

    invoke _tzset
    invoke printf, chr$(13,10,"64-bit Date and Time Functions - C Run-time Library",13,10)
    invoke _strtime, ADDR tmpbuf
    invoke printf, chr$(" OS time:                            %s",13,10), ADDR tmpbuf
    invoke _strdate, ADDR tmpbuf
    invoke printf,chr$(" OS date:                            %s",13,10), ADDR tmpbuf
    invoke _time64, ADDR time1
    invoke printf, chr$(" Time in seconds since UTC 1/1/1970: %I64u",13,10), time1
    invoke _ctime64, ADDR time1
    invoke printf, chr$(" Time and date string:               %s"), eax
    invoke _gmtime64, ADDR time1
    invoke asctime, eax
    invoke printf, chr$(" Coordinated universal time:         %s"), eax
    invoke _localtime64, ADDR time1
    mov edx, (tm PTR [eax]).tm_hour
    .if edx >= 12
        push eax
        push edx
        invoke strcpy, ADDR ampm, chr$("PM")
        pop edx
        pop eax
        sub edx, 12
        mov (tm PTR [eax]).tm_hour, edx
    .endif 
    mov edx, (tm PTR [eax]).tm_hour
    .if edx == 0
        mov (tm PTR [eax]).tm_hour, 12
    .endif
    invoke asctime, eax
    add eax, 11
    invoke printf, chr$( " 12-hour time:                       %.8s %s",13,10), eax, ADDR ampm
    invoke _ftime64, ADDR tstruct
    movsx eax, tstruct.millitm 
    invoke printf, chr$(" Plus milliseconds:                  %u",13,10), eax
    xor edx, edx
    movsx eax, tstruct.timezone
    mov ecx, 60
    div ecx
    invoke printf, chr$(" Zone difference in hours from UTC:  %u",13,10), eax
     invoke GetTimeZoneInformation,addr tziOld
      .if eax == TIME_ZONE_ID_STANDARD
         lea edx,tziOld.StandardName   
         invoke WideCharToMultiByte,CP_ACP,WC_COMPOSITECHECK,edx,\
            -1,addr timezone,sizeof timezone,NULL,NULL
         lea edx,timezone
               
      .elseif eax == TIME_ZONE_ID_DAYLIGHT
         lea edx,tziOld.DaylightName   
         invoke WideCharToMultiByte,CP_ACP,WC_COMPOSITECHECK,edx,\
            -1,addr timezone,sizeof timezone,NULL,NULL
         lea edx,timezone               
      .else
         mov edx,chr$("GTZI failed ")
      .endif
   mov     ptzname,edx         
    invoke printf, chr$(" Time zone name:                     %s",13,10), ptzname

        invoke printf, chr$( " Daylight savings:                   ")
    movsx eax, tstruct.dstflag
    .if eax == 0
        invoke printf, chr$("False",13,10)
    .else
        invoke printf, chr$("True",13,10)
    .endif
    invoke _localtime64, ADDR time1
    invoke strftime, ADDR tmpbuf, SIZEOF tmpbuf, chr$("%A, %B %d, %Y"), eax
    invoke printf, chr$(" Today is:                           %s",13,10), ADDR tmpbuf
    invoke _localtime64, ADDR time1
    mov edx, 11                     ; December
    mov (tm PTR [eax]).tm_mon, edx
    mov edx, 25                     ; 25th
    mov (tm PTR [eax]).tm_mday, edx
    mov edx, 12                     ; 12:00 noon   
    mov (tm PTR [eax]).tm_hour, edx
    mov edx, 0
    mov (tm PTR [eax]).tm_min, edx
    mov edx, 0
    mov (tm PTR [eax]).tm_sec, edx
    mov edx, 0
    mov (tm PTR [eax]).tm_wday, edx
    mov edx, 0
    mov (tm PTR [eax]).tm_yday, edx
    mov edx, 0
    mov (tm PTR [eax]).tm_isdst, edx
    mov pxmas, eax
    invoke _mktime64, eax
    mov DWORD PTR [time2+0], eax
    mov DWORD PTR [time2+4], edx
    .if DWORD PTR eax != -1 && DWORD PTR edx != -1
        invoke strftime, ADDR tmpbuf, SIZEOF tmpbuf, chr$("%A, %B %d, %Y"), pxmas
        invoke printf, chr$(" Christmas this year:                %s",13,10), ADDR tmpbuf
   .endif
    invoke _difftime64, ADDR time1, ADDR time2, ADDR diff
    finit
    fld diff
    fld day
    fdiv
    fstp days ;REAL8
   ;runtime error R6002 - floating point support not loaded fl
    invoke printf, chr$(" Days until Christmas:               %.0L",13,10), days
    ret
maincrt  ENDP

_difftime64 PROC pTime1:PTR QWORD, pTime2:PTR QWORD, pDiff:PTR REAL8
    ; MS Visual C Run-time Library does not have a _difftime64 function so...
    mov     eax, pTime1
    mov     edx, pTime2
    finit                   ; initialize FPU
    ; compare Time1 with Time2
    fild    QWORD PTR [edx] ; st(0) = Time2
    fild    QWORD PTR [eax] ; st(0) = Time1, st(1) = Time2
    fcompp                  ; compare st(0) with st(1) and pop both registers
    fstsw   ax              ; retrieve comparison result in the AX register
    fwait                   ; insure the previous instruction is completed
    sahf                    ; transfer the condition codes to the CPU's flag register
    jb      st0_less        ; only the C0 bit (CF flag) would be set if no error
st0_greater:                ; Time1 > Time2
    ;Subtract Time2 from Time1 to calculate the number of seconds difference
    mov     eax, pTime1
    mov     edx, pTime2
    fild    QWORD PTR [eax]
    fild    QWORD PTR [edx]
    fsub
    mov     eax, pDiff
    fstp    REAL8 PTR [eax]
    fwait
    jmp     @F
st0_less:                  ; Time2 > Time1
    ;Subtract Time1 from Time2 to calculate the number of seconds difference
    mov     eax, pTime2
    mov     edx, pTime1
    fild    QWORD PTR [eax]
    fild    QWORD PTR [edx]
    fsub
    mov     eax, pDiff
    fstp    REAL8 PTR [eax]
    fwait
@@:
    ret
_difftime64 ENDP

WaitKeyCrt PROC
    invoke printf, chr$(13,10,"Press any key to continue...")
    invoke _getch
    .if (eax == 0) || (eax == 0E0h)
        invoke _getch
    .endif
    invoke printf, ADDR newline   
    ret
WaitKeyCrt ENDP

END
Title: Re: I lose my time . Or CRT times functions
Post by: GregL on February 21, 2008, 07:17:45 PM
ToutEnMasm,

Well, the idea was to use the C Run-Time Library (versus the Windows API). I see _tzname has been deprecated in Visual C++ 2005, I wrote this when Visual C++ 2003 was the latest compiler. _tzname still works, it could be changed to _get_tzname if you are using msvcr80.dll or later. days is a REAL8 so "%.0lf" is a proper format string. It all works fine with the masm32 msvcrt.inc and .lib.

Note that Visual C++ 2005 added a _difftime64 function. It didn't exist with Visual C++ 2003 when I wrote this.

Glad you took a look at it. I'm going to download your windows.sdk and give it a try.

Title: Re: I lose my time . Or CRT times functions
Post by: GregL on February 21, 2008, 09:27:07 PM
ToutEnMasm,

I am trying to assemble the modified code you posted, with your 'windows.sdk', and I am having problems. I only changed the INCLUDE and INCLUDELIB paths.

Microsoft (R) Macro Assembler Version 6.15.8803
Copyright (C) Microsoft Corp 1981-2000.  All rights reserved.

Assembling: T:\test.asm
D:\ASM\MASM32\Libraries\sdk\mapinls.SDK(134) : error A2005: symbol redefinition : lstrlenW
D:\ASM\MASM32\Libraries\sdk\mapinls.SDK(135) : error A2005: symbol redefinition : lstrcmpW
D:\ASM\MASM32\Libraries\sdk\mapinls.SDK(136) : error A2005: symbol redefinition : lstrcpyW
D:\ASM\MASM32\Libraries\sdk\mapinls.SDK(137) : error A2005: symbol redefinition : CompareStringW
D:\ASM\MASM32\Libraries\sdk\mapinls.SDK(139) : error A2005: symbol redefinition : IsBadStringPtrW
T:\test.asm(17) : fatal error A1000: cannot open file : macro.inc


I don't have the 'macro.inc' file. If I use the masm32 'macros.asm' I get more errors. So I copied in the chr$ macro. Now I just get the symbol redefinition errors.

My code:

.486
.model flat, stdcall
option casemap :none

include D:\ASM\MASM32\Libraries\sdk\translate.inc
include D:\ASM\MASM32\Libraries\sdk\windows.sdk
include D:\ASM\MASM32\Libraries\sdk\stdio.sdk
include D:\ASM\MASM32\Libraries\sdk\conio.sdk
include D:\ASM\MASM32\Libraries\sdk\time.sdk
include D:\ASM\MASM32\Libraries\sdk\timeb.sdk   
include D:\ASM\MASM32\Libraries\sdk\mapiwin.sdk

includelib "C:\Program Files\Microsoft Visual Studio\VC98\Lib\libcmt.lib"
includelib "C:\Program Files\Microsoft Visual Studio\VC98\Lib\oldnames.lib"

;includelib c:\masm32\lib\kernel32.lib

;include macro.inc
chr$ MACRO any_text:VARARG
    LOCAL txtname
    .data
        txtname db any_text,0
    .code
    EXITM <OFFSET txtname>
ENDM
...

The rest is identical.


Title: Re: I lose my time . Or CRT times functions
Post by: ToutEnMasm on February 22, 2008, 08:40:57 AM
Thanks for testing it.
Redefinition of prototypes
Here is one problem of translation,masm don't accept prototypes redefinition,just put them in comment in the mapinis.sdk.C++ accept multiple definitions of the same prototype.
Quote
IF  NOTDEFINED(MAPI_NOWIDECHAR)
;lstrlenW   equ   < MNLS_lstrlenW>
;lstrcmpW   equ   < MNLS_lstrcmpW>
;lstrcpyW   equ   < MNLS_lstrcpyW>
;CompareStringW   equ   < MNLS_CompareStringW>
IF DEFINED(WIN16) OR DEFINED(_WINNT) OR DEFINED(_WIN95)
;IsBadStringPtrW   equ   < MNLS_IsBadStringPtrW>
ELSEIF DEFINED(_MAC)

Second Problem is that the masm32 package don't take care of compatibility with the sdk.Macro names in the 'macros.asm' have many conflicts of names.You can't use it.That can be done,is picking some macros in it and put them in a separate macro.inc .

This functions are 'Declared in Winbase.h, include Windows.h' ,this two files are included with:
Quote
include \masm32\sdk\windows.sdk               ;



Title: Re: I lose my time . Or CRT times functions
Post by: ToutEnMasm on February 22, 2008, 10:08:29 AM
I have made more testing with time functions of the vc++ msvcrt(libcmt).
_tzname is describe as follow
Quote
/* standard/daylight savings time zone names */
_CRTIMP extern char * _tzname[2];
This mean,pointer [deux pointeurs]  on a chain of bytes.
So i have the soluce
Quote
EXTERNDEF _tzname:DWORD
.code
.........
    invoke printf, chr$(" Zone difference in hours from UTC:  %u",13,10), eax
   mov eax,_tzname ;------------------------------------------------------------------------------
   mov ptzname,eax
    invoke printf, chr$(" Time zone name:                     %s",13,10), ptzname


With the vc++ 2008,the _difftime64  is in the msvcrt lib
just declare it as a c prototype and you can delet your proc
Quote
_difftime64 PROTO C :QWORD,:QWORD
.code
;time2 > time1
    invoke _difftime64,time2,time1
    fld day   ;REAL8
    fdiv
    fstp days ;REAL8
   ;runtime error R6002 - floating point support not loaded fl
    invoke printf, chr$(" Days until Christmas:               %6.0f",13,10),days


Some thing is wrong with the masm_msvcrt
Quote
mov eax, crt__tzname   ;----------- this return the adress of one chain with th VC++ msvcrt
.if tstruct.dstflag == 0
   mov edx, [eax+0]
   mov ptzname, edx
.else
   mov edx, [eax+4]
   mov ptzname, edx
.endif
To perform the same thing with the VC++ msvcrt
Quote
   lea edx,_tzname                           ;adress of pointers
   mov ecx,[edx]                             ; Winter time
   mov edx,[edx+4]                          ; Sun time



Title: Re: I lose my time . Or CRT times functions
Post by: GregL on February 22, 2008, 07:29:35 PM
ToutEnMasm,

OK, this is working with the 'windows.sdk' include files. I commented out the lines in 'mapinis.sdk'. I did not modify the _tzname code and it's working correctly. I'm using Visual C++ 2008.


.486
.MODEL FLAT, STDCALL
OPTION CASEMAP:NONE

INCLUDE D:\ASM\MASM32\Libraries\sdk\translate.inc
INCLUDE D:\ASM\MASM32\Libraries\sdk\windows.sdk
INCLUDE D:\ASM\MASM32\Libraries\sdk\stdio.sdk
INCLUDE D:\ASM\MASM32\Libraries\sdk\conio.sdk
INCLUDE D:\ASM\MASM32\Libraries\sdk\time.sdk
INCLUDE D:\ASM\MASM32\Libraries\sdk\timeb.sdk   
INCLUDE D:\ASM\MASM32\Libraries\sdk\mapiwin.sdk

INCLUDELIB "C:\Program Files\Microsoft SDKs\Windows\v6.1\Lib\kernel32.lib"

; static CRT
;INCLUDELIB "C:\Program Files\Microsoft Visual Studio 9.0\VC\lib\libcmt.lib" 
; dynamic CRT
INCLUDELIB "C:\Program Files\Microsoft Visual Studio 9.0\VC\lib\msvcrt.lib"

_difftime64 PROTO C :QWORD,:QWORD
           
WaitKeyCrt PROTO

EXTERNDEF _tzname:DWORD

TEXT MACRO txt:VARARG
    LOCAL txtname
    .DATA
        txtname BYTE txt,0
    ALIGN 4
    .CODE
        EXITM <ADDR txtname>
ENDM

.DATA

    ALIGN 8
    time1     QWORD     0
    time2     QWORD     0
    diff      REAL8     0.0
    day       REAL8     86400.0  ; 60*60*24
    days      REAL8     0.0
    tstruct   __timeb64 <0>
    ALIGN 4
    hmodule   DWORD     0
    pxmas     DWORD     0
    ptzname   DWORD     0
    tmpbuf    BYTE      128 DUP(0)
    ampm      BYTE      "AM", 0
    newline   BYTE      13, 10, 0
   
.CODE

main PROC

   LOCAL dwRet:DWORD
   LOCAL timezone[64]:BYTE

    ;INVOKE _tzset    ; optional
    INVOKE printf, TEXT(13,10,"64-bit Date and Time Functions - C Run-time Library",13,10)
    INVOKE _strtime, ADDR tmpbuf
    INVOKE printf, TEXT(" OS time:                            %s",13,10), ADDR tmpbuf
    INVOKE _strdate, ADDR tmpbuf
    INVOKE printf,TEXT(" OS date:                            %s",13,10), ADDR tmpbuf
    INVOKE _time64, ADDR time1
    INVOKE printf, TEXT(" Time in seconds since UTC 1/1/1970: %I64u",13,10), time1
    INVOKE _ctime64, ADDR time1
    INVOKE printf, TEXT(" Time and date string:               %s"), eax
    INVOKE _gmtime64, ADDR time1
    INVOKE asctime, eax
    INVOKE printf, TEXT(" Coordinated universal time:         %s"), eax
    INVOKE _localtime64, ADDR time1
    mov edx, (tm PTR [eax]).tm_hour
    .if edx >= 12
        push eax
        push edx
        INVOKE strcpy, ADDR ampm, TEXT("PM")
        pop edx
        pop eax
        sub edx, 12
        mov (tm PTR [eax]).tm_hour, edx
    .endif 
    mov edx, (tm PTR [eax]).tm_hour
    .if edx == 0
        mov (tm PTR [eax]).tm_hour, 12
    .endif
    INVOKE asctime, eax
    add eax, 11
    INVOKE printf, TEXT( " 12-hour time:                       %.8s %s",13,10), eax, ADDR ampm
    INVOKE _ftime64, ADDR tstruct
    movsx eax, tstruct.millitm 
    INVOKE printf, TEXT(" Plus milliseconds:                  %u",13,10), eax
    xor edx, edx
    movsx eax, tstruct.timezone
    mov ecx, 60
    div ecx
    INVOKE printf, TEXT(" Zone difference in hours from UTC:  %u",13,10), eax
    mov eax, _tzname
    .IF tstruct.dstflag == 0
        mov edx, [eax+0] 
        mov ptzname, edx
    .ELSE
        mov edx, [eax+4] 
        mov ptzname, edx
    .ENDIF
    INVOKE printf, TEXT(" Time zone name:                     %s",13,10), ptzname
    INVOKE printf, TEXT( " Daylight savings:                   ")
    movsx eax, tstruct.dstflag
    .IF eax == 0
        INVOKE printf, TEXT("False",13,10)
    .ELSE
        INVOKE printf, TEXT("True",13,10)
    .ENDIF
    INVOKE _localtime64, ADDR time1
    INVOKE strftime, ADDR tmpbuf, SIZEOF tmpbuf, TEXT("%A, %B %d, %Y"), eax
    INVOKE printf, TEXT(" Today is:                           %s",13,10), ADDR tmpbuf
    INVOKE _localtime64, ADDR time1
    mov edx, 11                     ; December
    mov (tm PTR [eax]).tm_mon, edx
    mov edx, 25                     ; 25th
    mov (tm PTR [eax]).tm_mday, edx
    mov edx, 12                     ; 12:00 noon   
    mov (tm PTR [eax]).tm_hour, edx
    mov edx, 0
    mov (tm PTR [eax]).tm_min, edx
    mov edx, 0
    mov (tm PTR [eax]).tm_sec, edx
    mov edx, 0
    mov (tm PTR [eax]).tm_wday, edx
    mov edx, 0
    mov (tm PTR [eax]).tm_yday, edx
    mov edx, 0
    mov (tm PTR [eax]).tm_isdst, edx
    mov pxmas, eax
    INVOKE _mktime64, eax
    mov DWORD PTR [time2+0], eax
    mov DWORD PTR [time2+4], edx
    .IF DWORD PTR eax != -1 && DWORD PTR edx != -1
        INVOKE strftime, ADDR tmpbuf, SIZEOF tmpbuf, TEXT("%A, %B %d, %Y"), pxmas
        INVOKE printf, TEXT(" Christmas this year:                %s",13,10), ADDR tmpbuf
    .ENDIF
    INVOKE _difftime64, time2, time1
    fld day
    fdiv
    fstp days ;REAL8
    INVOKE printf, TEXT(" Days until Christmas:               %.0lf",13,10), days
    INVOKE WaitKeyCrt
    INVOKE _exit, 0
main ENDP

WaitKeyCrt PROC
    INVOKE printf, TEXT(13,10,"Press any key to continue...")
    INVOKE _getch
    .IF (eax == 0) || (eax == 0E0h)
        INVOKE _getch
    .ENDIF
    INVOKE printf, ADDR newline   
    ret
WaitKeyCrt ENDP

END main

Title: Re: I lose my time . Or CRT times functions
Post by: ToutEnMasm on February 22, 2008, 08:16:58 PM

I have two littles problems
--------- I need that main be a PROC C   with the correct 'end' for code
--------
Quote
lea edx, _tzname
.IF tstruct.dstflag == 0
mov edx, [edx+0]
mov ptzname, edx
.ELSE
mov edx, [edx+4]
mov ptzname,edx
.ENDIF

Seem strange to me ?



Title: Re: I lose my time . Or CRT times functions
Post by: ToutEnMasm on February 22, 2008, 08:27:49 PM
I post the code that work for me

Quote
.NOLIST         ;signifie: ne rien mettre dans le listing
.486
   .MODEL FLAT, STDCALL
   OPTION CASEMAP:NONE

   INCLUDE \masm32\sdk\translate.inc
   INCLUDE \masm32\sdk\windows.sdk
   INCLUDE \masm32\sdk\stdio.sdk
   INCLUDE \masm32\sdk\conio.sdk
   INCLUDE \masm32\sdk\time.sdk
   INCLUDE \masm32\sdk\timeb.sdk
   INCLUDE \masm32\sdk\mapiwin.sdk
   includelib C:\PROGRA~1\MICROS~1.0\VC\lib\msvcrt.lib   
   includelib C:\PROGRA~1\MICROS~1.0\VC\lib\oldnames.lib
      
   includelib c:\masm32\lib\kernel32.lib
   main PROTO C

   _difftime64 PROTO C :QWORD,:QWORD

   WaitKeyCrt PROTO

   EXTERNDEF _tzname:DWORD

   TEXT MACRO txt:VARARG
   LOCAL txtname
   .DATA
      txtname BYTE txt,0
      ALIGN 4
   .CODE
   EXITM <ADDR txtname>
   ENDM

.DATA

   ALIGN 8
   time1 QWORD 0
   time2 QWORD 0
   diff REAL8 0.0
   day REAL8 86400.0 ; 60*60*24
   days REAL8 0.0
   tstruct __timeb64 <0>
   ALIGN 4
   hmodule DWORD 0
   pxmas DWORD 0
   ptzname DWORD 0
   tmpbuf BYTE 128 DUP(0)
   ampm BYTE "AM", 0
   newline BYTE 13, 10, 0

.CODE

main PROC C

   LOCAL dwRet:DWORD
   LOCAL timezone[64]:BYTE

   ;INVOKE _tzset ; optional
   INVOKE printf, TEXT(13,10,"64-bit Date and Time Functions - C Run-time Library",13,10)
   INVOKE _strtime, ADDR tmpbuf
   INVOKE printf, TEXT(" OS time: %s",13,10), ADDR tmpbuf
   INVOKE _strdate, ADDR tmpbuf
   INVOKE printf,TEXT(" OS date: %s",13,10), ADDR tmpbuf
   INVOKE _time64, ADDR time1
   INVOKE printf, TEXT(" Time in seconds since UTC 1/1/1970: %I64u",13,10), time1
   INVOKE _ctime64, ADDR time1
   INVOKE printf, TEXT(" Time and date string: %s"), eax
   INVOKE _gmtime64, ADDR time1
   INVOKE asctime, eax
   INVOKE printf, TEXT(" Coordinated universal time: %s"), eax
   INVOKE _localtime64, ADDR time1
   mov edx, (tm PTR [eax]).tm_hour
   .if edx >= 12
      push eax
      push edx
      INVOKE strcpy, ADDR ampm, TEXT("PM")
      pop edx
      pop eax
      sub edx, 12
      mov (tm PTR [eax]).tm_hour, edx
   .endif
   mov edx, (tm PTR [eax]).tm_hour
   .if edx == 0
      mov (tm PTR [eax]).tm_hour, 12
   .endif
   INVOKE asctime, eax
   add eax, 11
   INVOKE printf, TEXT( " 12-hour time: %.8s %s",13,10), eax, ADDR ampm
   INVOKE _ftime64, ADDR tstruct
   movsx eax, tstruct.millitm
   INVOKE printf, TEXT(" Plus milliseconds: %u",13,10), eax
   xor edx, edx
   movsx eax, tstruct.timezone
   mov ecx, 60
   div ecx
   INVOKE printf, TEXT(" Zone difference in hours from UTC: %u",13,10), eax
   lea edx, _tzname
   .IF tstruct.dstflag == 0
      mov edx, [edx+0]
      mov ptzname, edx
   .ELSE
      mov edx, [edx+4]
      mov ptzname,edx
   .ENDIF
   INVOKE printf, TEXT(" Time zone name: %s",13,10), ptzname
   INVOKE printf, TEXT( " Daylight savings: ")
   movsx eax, tstruct.dstflag
   .IF eax == 0
      INVOKE printf, TEXT("False",13,10)
   .ELSE
      INVOKE printf, TEXT("True",13,10)
   .ENDIF
   INVOKE _localtime64, ADDR time1
   INVOKE strftime, ADDR tmpbuf, SIZEOF tmpbuf, TEXT("%A, %B %d, %Y"), eax
   INVOKE printf, TEXT(" Today is: %s",13,10), ADDR tmpbuf
   INVOKE _localtime64, ADDR time1
   mov edx, 11 ; December
   mov (tm PTR [eax]).tm_mon, edx
   mov edx, 25 ; 25th
   mov (tm PTR [eax]).tm_mday, edx
   mov edx, 12 ; 12:00 noon
   mov (tm PTR [eax]).tm_hour, edx
   mov edx, 0
   mov (tm PTR [eax]).tm_min, edx
   mov edx, 0
   mov (tm PTR [eax]).tm_sec, edx
   mov edx, 0
   mov (tm PTR [eax]).tm_wday, edx
   mov edx, 0
   mov (tm PTR [eax]).tm_yday, edx
   mov edx, 0
   mov (tm PTR [eax]).tm_isdst, edx
   mov pxmas, eax
   INVOKE _mktime64, eax
   mov DWORD PTR [time2+0], eax
   mov DWORD PTR [time2+4], edx
   .IF DWORD PTR eax != -1 && DWORD PTR edx != -1
      INVOKE strftime, ADDR tmpbuf, SIZEOF tmpbuf, TEXT("%A, %B %d, %Y"), pxmas
      INVOKE printf, TEXT(" Christmas this year: %s",13,10), ADDR tmpbuf
   .ENDIF
   INVOKE _difftime64, time2, time1
   fld day
   fdiv
   fstp days ;REAL8
   INVOKE printf, TEXT(" Days until Christmas: %.0lf",13,10), days
   INVOKE WaitKeyCrt
   ret
main ENDP

WaitKeyCrt PROC
   INVOKE printf, TEXT(13,10,"Press any key to continue...")
   INVOKE _getch
   .IF (eax == 0) || (eax == 0E0h)
      INVOKE _getch
   .ENDIF
   INVOKE printf, ADDR newline
ret
WaitKeyCrt ENDP

END
Title: Re: I lose my time . Or CRT times functions
Post by: GregL on February 22, 2008, 08:47:05 PM
ToutEnMasm,

1. Does "END main" work?

2. This does not work correctly for me

   lea edx, _tzname
   .IF tstruct.dstflag == 0
      mov edx, [edx+0]
      mov ptzname, edx
   .ELSE
      mov edx, [edx+4]
      mov ptzname,edx
   .ENDIF


This does

    mov eax, _tzname
    .IF tstruct.dstflag == 0
        mov edx, [eax+0] 
        mov ptzname, edx
    .ELSE
        mov edx, [eax+4] 
        mov ptzname, edx
    .ENDIF


It doesn't matter whether it's static or dynamic.

Which version of the .lib files are you linking to? Which version of Visual C++ are you using?

Title: Re: I lose my time . Or CRT times functions
Post by: ToutEnMasm on February 22, 2008, 08:54:15 PM
End main ,don't work.
the normal entry point is:
.code
main proc c
main endp
other Proc
other endp
end

Is that i don't understand with your code,it must create one error,No ?

I use vc++ 2008 and XP sp2

Title: Re: I lose my time . Or CRT times functions
Post by: GregL on February 22, 2008, 09:01:07 PM
I am not getting any errors. ??

Title: Re: I lose my time . Or CRT times functions
Post by: ToutEnMasm on February 22, 2008, 09:03:46 PM

Try to modify the end main,end is normally enough.
Title: Re: I lose my time . Or CRT times functions
Post by: GregL on February 22, 2008, 09:08:04 PM
If I remove 'main' from 'END' I get an error:
msvcrt.lib(crtexe.obj) : error LNK2019: unresolved external symbol _main referenced in function ___tmainCRTStartup
Title: Re: I lose my time . Or CRT times functions
Post by: ToutEnMasm on February 22, 2008, 09:13:12 PM

I have just added the defined of the main proto in your code.
This time , i have tried to make main standard proc,added the end main and ......
I must have change the lea eax,_tzname ,to be as yours.
There is something fun here.
Title: Re: I lose my time . Or CRT times functions
Post by: ToutEnMasm on February 22, 2008, 09:21:10 PM
Quote
If I remove 'main' from 'END' I get an error:
msvcrt.lib(crtexe.obj) : error LNK2019: unresolved external symbol _main referenced in function ___tmainCRTStartup
You must put the main proc in C,this enough.
main proto c


Title: Re: I lose my time . Or CRT times functions
Post by: GregL on February 22, 2008, 09:51:39 PM
ToutEnMasm,

My code works fine if I link to msvcrt.lib.

If I link to libcmt.lib, then I have problems.

Your includes work fine, it's just a matter of fine tuning the code depending on whether one links dynamically or statically.

I'm going to play around with it later, I have got some things I need to get done.

Cheers

Title: Re: I lose my time . Or CRT times functions
Post by: GregL on February 22, 2008, 10:02:28 PM
ToutEnMasm,

QuoteYou must put the main proc in C,this enough.
main proto c

That does work, but it works the other way as well.

I gotta go. Talk to you later.

Title: Re: I lose my time . Or CRT times functions
Post by: ToutEnMasm on February 22, 2008, 10:08:42 PM

You are right, the libcmt want
Quote
   lea eax, _tzname
   .IF tstruct.dstflag == 0
      mov edx, [eax+0]
      mov ptzname, edx
   .ELSE
      mov edx, [eax+4]
      mov ptzname,edx
   .ENDIF

the msvcrt want
Quote
   mov eax, _tzname
   .IF tstruct.dstflag == 0
      mov edx, [eax+0]
      mov ptzname, edx
   .ELSE
      mov edx, [eax+4]
      mov ptzname,edx
   .ENDIF

It isn't the same thing

a+
Title: Re: I lose my time . Or CRT times functions
Post by: GregL on February 22, 2008, 10:13:09 PM
ToutEnMasm,

Yes, I agree. I am seeing the same thing.