News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

I lose my time . Or CRT times functions

Started by ToutEnMasm, February 19, 2008, 02:22:31 PM

Previous topic - Next topic

GregL

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.


GregL

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.



ToutEnMasm

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               ;




ToutEnMasm

#18
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




GregL

#19
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


ToutEnMasm


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 ?




ToutEnMasm

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

GregL

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?


ToutEnMasm

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


GregL


ToutEnMasm


Try to modify the end main,end is normally enough.

GregL

If I remove 'main' from 'END' I get an error:
msvcrt.lib(crtexe.obj) : error LNK2019: unresolved external symbol _main referenced in function ___tmainCRTStartup

ToutEnMasm


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.

ToutEnMasm

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



GregL

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