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
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]
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>
;---------------------------------------------------------------------------------------------------------------------
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.
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.
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.
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.
Vortex,
Please explain how that msvcrt.lib is different from the one in the MASM32 package?
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]
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]
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.
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.
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.
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.
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
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.
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.
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 ;
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
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
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 ?
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
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?
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
I am not getting any errors. ??
Try to modify the end main,end is normally enough.
If I remove 'main' from 'END' I get an error:
msvcrt.lib(crtexe.obj) : error LNK2019: unresolved external symbol _main referenced in function ___tmainCRTStartup
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.
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
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
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.
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+
ToutEnMasm,
Yes, I agree. I am seeing the same thing.