News:

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

Calling GetLocalTime on windows

Started by pelmeen, December 27, 2011, 09:14:44 PM

Previous topic - Next topic

pelmeen

I cant understand what am i doing wrong in this piece of code. Can anyone help, please?
The goal is to get system time and if i get that working, then im going to start turning it into random. Right now, i just want the big number

getRandom proc C
   LOCAL timeWord:dword
   invoke GetLocalTime,timeWord
   mov eax, timeWord
   ret
getRandom endp

Refrence:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms724338%28v=vs.85%29.aspx

Thank you.

qWord

Quote from: msdnA pointer to a SYSTEMTIME structure to receive the current local date and time
LOCAL systime:SYSTEMTIME
...
invoke GetLocalTime,ADDR systime
FPU in a trice: SmplMath
It's that simple!

pelmeen

SYSTEMTIME requires winbase.h. It says to include windows.h
I started researching windows.h and found this site:
http://en.wikipedia.org/wiki/Windows.h
In here it says that:

winbase.h – kernel32.dll: kernel services

In my program, i already have

PUBLIC getRandom

include \masm32\include\kernel32.inc
includelib \masm32\lib\kernel32.lib

getRandom proc C
   LOCAL systime:SYSTEMTIME
   invoke GetLocalTime,ADDR systime
   mov eax, systime
   ret
getRandom endp


But i still get error:
lib\random.asm(19) : error A2006: undefined symbol : SYSTEMTIME
lib\random.asm(19) : error A2195: parameter or local cannot have void type
lib\random.asm(21) : error A2006: undefined symbol : timeWord

Why cant it find SYSTEMTIME

Im really sorry, if this is stupid question, im very new to this ultimate hacking language

jj2007

If you have downloaded the Masm32 SDK, this will work. If not, click on my signature and download the SDK.

include \masm32\include\masm32rt.inc

.code
getRandom proc C
   LOCAL systime:SYSTEMTIME
   invoke GetLocalTime,ADDR systime
   movsx eax, systime.wMilliseconds
   ret
getRandom endp
start:
MsgBox 0, str$(rv(getRandom)), "wMilliseconds:", MB_OK
exit

end start

qWord

FPU in a trice: SmplMath
It's that simple!

pelmeen

Thank you very much guys. It does return something now.

However, it only return 3 digit number, the milliseconds. I need the big number. Milliseconds from 1970. UNIX time. How change it to do that? Looking at the SYSTEMTIME info i can only see that i can get specific days, hours, minutes and such. No use to me. Too small of a number.

jj2007

Here is a big number. Console assemble & link.

include \masm32\include\masm32rt.inc

.code
getRandom proc uses ebx esi
   LOCAL systime:FILETIME, dosTime:WORD, dosDate:WORD
   lea ebx, systime
   invoke GetSystemTimeAsFileTime, ebx
   lea esi, dosDate
   lea ecx, dosTime
   invoke FileTimeToDosDateTime, ebx, esi, ecx
   lodsw
   shl eax, 16
   lodsw
   ret
getRandom endp

start: m2m ebx, 7
.Repeat
invoke getRandom
print str$(eax), 13, 10
invoke Sleep, 1000
dec ebx
.Until Sign?
exit
end start

pelmeen

Thank you for your reply. Im at work right now, il check it when i get home in the evening.

I did notice though that you used 2 completely different functions then i did. Il check it out later.

dedndave

QuoteI need the big number. Milliseconds from 1970. UNIX time.

you are looking for what MS refers to as "time_t" time
the MSVCRT library has a "time" function...
QuoteThe time function returns the number of seconds elapsed since midnight (00:00:00), January 1, 1970,
Coordinated Universal Time (UTC), according to the system clock. The return value is stored in the location
given by timer. This parameter may be NULL, in which case the return value is not stored.

http://msdn.microsoft.com/en-us/library/1f4c8f33%28VS.80%29.aspx

if you want milliseconds instead of seconds, multiply by 1000   :bg

QuoteUnix time, or POSIX time, is a system for describing instants in time, defined as the number of
seconds elapsed since midnight Coordinated Universal Time (UTC) of Thursday, January 1, 1970

i guess this system runs out of poop in 2038
i am sure there will be some 64-bit version of it, by then
i will be 83, and probably won't care   :P

pelmeen

I just went through jj2007 code and then read through dedndave description. I also ran the code i have been given.. And dedndave speaks the truth. Its seconds from 1970, not milliseconds.

I just realized that my task got a lot harder. I cant use seconds, since i need more than 1 randoms in a second.

Also, i cant use the three digit milliseconds, because i need randoms up to 5 digits long

If you have any suggestions, it would be appreciated, in the mean while, im going to search for some mathematical formula, to see if i can get 5 digit random from 3 digit number. I wont get my hopes up too much.

EDIT:
Well what can i say? I just got a whole alot smarter and it turns out i CAN use the milliseconds. And i taught i know what pseudo-random number is
Thank all of you guys SO much. Its time for me to get to work. I will let you know if i have any problems or if i was successful

jj2007

Quote from: pelmeen on December 28, 2011, 07:34:15 PMAlso, i cant use the three digit milliseconds, because i need randoms up to 5 digits long

If that's all what you need, here is one:

include \masm32\MasmBasic\MasmBasic.inc   ; download
   Init
   Inkey Str$("A random number between 0 and 9999: %i", Rand(10000))
   Exit
end start

It's also the fastest one available - credits to Alex alias Antariy :bg

pelmeen

Heh, thank you, but if i would go down on such an easy road, then i would learn nothing :)

I will try to do it myself, but i appreciate the effort.

dedndave

first of all, i would not depend strictly on any time function for the random values
particularly if you are grabbing values more than once a second   :P

you will be much happier with the results if you use a simple random number generator, like LCG
then, use one of the time functions to periodically seed/re-seed the generator
(QueryPerformanceCounter, GetTickCount or even the RDTSC instruction)

there are many variations on a theme
a while back i wrote a simple routine that auto-seeds itself
it's only an example to give you some ideas...

http://www.masm32.com/board/index.php?topic=11679.msg123908#msg123908

pelmeen

Well i really wanted to write a random number generator myself. Right now i made something that will be reseeded every time random is called.

I used the same thing C Rand() function does

You dont think its solid enough?


getRandom proc C
   LOCAL systime:SYSTEMTIME
   invoke GetLocalTime,ADDR systime
   movsx eax, systime.wMilliseconds
   imul eax, 1103515245
   add eax, 12345
   xor edx, edx
   mov ebx, 65536
   idiv ebx
   xor edx, edx
   mov ebx, 32768
   idiv ebx
   mov eax, edx
   ret
getRandom endp


jj2007

Quote from: pelmeen on December 28, 2011, 09:57:15 PM
Well i really wanted to write a random number generator myself.

QuoteI used the same thing C Rand() function does
You dont think its solid enough?

Here is ENT, A Pseudorandom Number Sequence Test Program. The MasmBasic Rand() macro shown above has been optimised for ENT, and is fast: 11-12 cycles per call. For comparison, your routine above takes about 30 cycles without the API call, and 425 cycles including the GetLocalTime call.