The MASM Forum

General => The Campus => Topic started by: deeR44 on August 06, 2022, 02:44:59 PM

Title: GetSystemTime in Assembly Language
Post by: deeR44 on August 06, 2022, 02:44:59 PM

How do I call "GetSystemTime" in Assembler?
I only found a dozen, or so, in C/C++.
Title: Re: GetSystemTime in Assembly Language
Post by: Vortex on August 06, 2022, 05:27:20 PM
Hello deeR44,

Here is a quick example :


include     \masm32\include\masm32rt.inc

.data

str1        db '%0.2d.%0.2d.%d-%0.2d.%0.2d.%0.2d',0

.data?

_st          SYSTEMTIME <?>

.code

start:

    invoke  GetSystemTime,ADDR _st

    mov     edx,OFFSET _st

    movzx   eax,WORD PTR SYSTEMTIME.wSecond[edx]
    push    eax

    movzx   eax,WORD PTR SYSTEMTIME.wMinute[edx]
    push    eax

    movzx   eax,WORD PTR SYSTEMTIME.wHour[edx]
    push    eax

    movzx   eax,WORD PTR SYSTEMTIME.wYear[edx]
    push    eax

    movzx   eax,WORD PTR SYSTEMTIME.wMonth[edx]
    push    eax

    movzx   eax,WORD PTR SYSTEMTIME.wDay[edx]
    push    eax

    push    OFFSET str1
   
    call    crt_printf
    add     esp,4*7   

    invoke  ExitProcess,0

END start
Title: Re: GetSystemTime in Assembly Language
Post by: jj2007 on August 06, 2022, 07:46:12 PM
Quote from: Vortex on August 06, 2022, 05:27:20 PM
Here is a quick example :

A very elegant way to do it, compliments, Erol :thumbsup:
Title: Re: GetSystemTime in Assembly Language
Post by: NoCforMe on August 07, 2022, 04:47:10 AM
So, @deeR44, just so you know what's going on there (yes, the example is elegant, but also terse, and probably incomprehensible to you without some explanation):

What they're doing is this:

1. Calling GetSystemTime(), which puts the current time into a structure of type SYSTEMTIME. (Values here are binary: year, month, day, hour, etc.)

2. Setting a pointer to this structure:
   mov     edx,OFFSET _st

3. Pulling values out of the structure via the pointer and pushing them on the stack:
    movzx   eax,WORD PTR SYSTEMTIME.wSecond[edx]
    push    eax

(since the values are WORDS, we have to use MOVZX here to magically transform a WORD value in memory into a DWORD which goes into EAX)

4. Pushing a pointer to str1 on the stack. This is a special type of string called a format string. The format control specifications start with a "%" character, like %0.2d, and tell crt_printf to turn a binary value into ASCII text (here, the "d" character means "decimal"). The rest of the string gets printed as-is. For example, the format string
"The number is %d", 0
would print "The number is 10" for a value of 10 for that format specifier. (Don't forget the terminating 0 at the end!)

5. Calling crt_printf to print the formatted string.

So far as pushing all that stuff on the stack goes, it is done in reverse order to the parameters of the function/macro (last parameter first).


Title: Re: GetSystemTime in Assembly Language
Post by: deeR44 on August 07, 2022, 11:44:22 AM
Quote from: Vortex on August 06, 2022, 05:27:20 PM
Hello deeR44,

Here is a quick example :

Thank you, but I screwed up.  I meant DATETIME or FILETIME.
Title: Re: GetSystemTime in Assembly Language
Post by: NoCforMe on August 07, 2022, 11:47:50 AM
I think those are both structures, not functions. Is that what you're looking for? You'd need a function to fill them with the desired contents.

What are you trying to do?
Title: Re: GetSystemTime in Assembly Language
Post by: deeR44 on August 07, 2022, 11:55:12 AM
Quote from: NoCforMe on August 07, 2022, 11:47:50 AM
I think those are both structures, not functions. Is that what you're looking for? You'd need a function to fill them with the desired contents.

What are you trying to do?
I think that I can come up with the structure. What I don't know is how to access the API function that returns
the DATETIME or FILETIME to the structure.
Title: Re: GetSystemTime in Assembly Language
Post by: NoCforMe on August 07, 2022, 12:12:47 PM
Looks like GetFileTime() is your friend for file time. (MSDN page here. (https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getfiletime)) It returns 3 times in 3 separate FILETIME structures (creation time, last access time and last write time).

You need to pass it a file handle. Do you know how to get that for a file you're interested in?


BOOL GetFileTime(
  [in]            HANDLE     hFile,
  [out, optional] LPFILETIME lpCreationTime,
  [out, optional] LPFILETIME lpLastAccessTime,
  [out, optional] LPFILETIME lpLastWriteTime
);
Title: Re: GetSystemTime in Assembly Language
Post by: deeR44 on August 07, 2022, 12:49:43 PM
Quote from: NoCforMe on August 07, 2022, 12:12:47 PM
Looks like GetFileTime() is your friend for file time. (MSDN page here. (https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getfiletime)) It returns 3 times in 3 separate FILETIME structures (creation time, last access time and last write time).

You need to pass it a file handle. Do you know how to get that for a file you're interested in?


BOOL GetFileTime(
  [in]            HANDLE     hFile,
  [out, optional] LPFILETIME lpCreationTime,
  [out, optional] LPFILETIME lpLastAccessTime,
  [out, optional] LPFILETIME lpLastWriteTime
);

I saw this function--not what I want. I just want the current time (DATETIME or FILETIME) to go into
the appropriate structure. Not involved with a file.
Title: Re: GetSystemTime in Assembly Language
Post by: NoCforMe on August 07, 2022, 01:27:06 PM
No such structure as DATETIME that I can find.

Here's some code to format the current time into a string from a program I wrote:

Proj_HeaderFmt DB "File created on %u/%u/%u at %u:%02u %s", 0

AMstr DB "am", 0
PMstr DB "pm", 0

LOCAL ts:SYSTEMTIME, day:DWORD, month:DWORD, year:DWORD, hour:DWORD, minute:DWORD, buffer[256]:BYTE

INVOKE GetLocalTime, ADDR ts
LEA EDX, AMstr
MOVZX EAX, ts.wHour
OR EAX, EAX
JNZ @F
MOV EAX, 12
@@: CMP EAX, 13
JB @F
LEA EDX, PMstr
SUB EAX, 12
@@: MOV hour, EAX
MOVZX EAX, ts.wYear
MOV year, EAX
MOVZX EAX, ts.wMonth
MOV month, EAX
MOVZX EAX, ts.wDay
MOV day, EAX
MOVZX EAX, ts.wMinute
MOV minute, EAX
INVOKE wsprintf, ADDR buffer, OFFSET Proj_HeaderFmt, month, day, year, hour, minute, EDX


GetLocalTime() puts the values that make up the current time into a structure of type SYSTEMTIME. The code processes these values: turns the 24-hour based hour into a 12-hour one (and corrects for midnight to 1am. which is zero in 24-hour time), and puts "am" or "pm" in the string as appropriate. When it's done the formatted string is in the variable buffer.

Notice all the MOVZXs, used because the values are WORDs that need to be moved to DWORD registers or variables.
Title: Re: GetSystemTime in Assembly Language
Post by: deeR44 on August 07, 2022, 03:08:08 PM
Quote from: NoCforMe on August 07, 2022, 01:27:06 PM
No such structure as DATETIME that I can find.

Here's some code to format the current time into a string from a program I wrote:
I can make up the structure for DATETIME/FILETIME. That's no problem. I just need to find the
API procedure that returns DATETIME/FILETIME to the structure.

Title: Re: GetSystemTime in Assembly Language
Post by: NoCforMe on August 07, 2022, 03:42:47 PM
I don't think FILETIME is what you want to use. Here's the MSDN page (https://docs.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-filetime) on that structure. It keeps the file time as a 64-bit value (in two DWORDs), not individual fields like hour, minute, etc.

If you do want to use this structure, then GetFileTime() is the function to call. (MSDN page here (https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getfiletime).)
Title: Re: GetSystemTime in Assembly Language
Post by: Vortex on August 07, 2022, 06:31:19 PM
Thanks to NoCforMe for the explanation. A small comment to add :

    call    crt_printf
    add     esp,4*7 


Since printf is a C function, the stack must be balanced. The built-in invoke macro does it automatically but after call crt_printf, 4 bytes \ Dword * 7 parameters must be added to the stack.
Title: Re: GetSystemTime in Assembly Language
Post by: jj2007 on August 07, 2022, 06:33:36 PM
Deer44,

Please do yourself a favour and get the Win32 help file. Inside this page (https://www.jj2007.eu/Masm32_Tips_Tricks_and_Traps.htm) you'll find a link to the Modula page.
Title: Re: GetSystemTime in Assembly Language
Post by: NoCforMe on August 07, 2022, 06:51:04 PM
... or learn how to find information on MSDN. Everything you need is there. Just need to do a little digging.
Title: Re: GetSystemTime in Assembly Language
Post by: deeR44 on August 11, 2022, 11:31:51 AM
Quote from: jj2007 on August 07, 2022, 06:33:36 PM
Deer44,

Please do yourself a favour and get the Win32 help file. Inside this page (https://www.jj2007.eu/Masm32_Tips_Tricks_and_Traps.htm) you'll find a link to the Modula page.
My 7z program won't open this zip file in your post. Says that it's invalid.

Title: Re: GetSystemTime in Assembly Language
Post by: NoCforMe on August 11, 2022, 12:01:18 PM
If you tried to open the zip file in reply #13, it won't work because it's just a picture. Use the link ("this page") in the message instead.

Here's that link (https://www.modula2.org/win32tutor/references.php) (I took it from JJ's page, saves you one click). The help file is in the link under the heading "Win32 API Help file" on that page. Highly recommend downloading it so you have all that info right there on your own computah.

(Little trick: you can display pictures in posts here by renaming an image file (JPG, PNG, etc.) to [something].zip.)