News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

GetSystemTime in Assembly Language

Started by deeR44, August 06, 2022, 02:44:59 PM

Previous topic - Next topic

deeR44


How do I call "GetSystemTime" in Assembler?
I only found a dozen, or so, in C/C++.

Vortex

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

jj2007

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:

NoCforMe

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).


Assembly language programming should be fun. That's why I do it.

deeR44

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.

NoCforMe

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?
Assembly language programming should be fun. That's why I do it.

deeR44

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.

NoCforMe

Looks like GetFileTime() is your friend for file time. (MSDN page here.) 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
);
Assembly language programming should be fun. That's why I do it.

deeR44

Quote from: NoCforMe on August 07, 2022, 12:12:47 PM
Looks like GetFileTime() is your friend for file time. (MSDN page here.) 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.

NoCforMe

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.
Assembly language programming should be fun. That's why I do it.

deeR44

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.


NoCforMe

I don't think FILETIME is what you want to use. Here's the MSDN page 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.)
Assembly language programming should be fun. That's why I do it.

Vortex

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.

jj2007

Deer44,

Please do yourself a favour and get the Win32 help file. Inside this page you'll find a link to the Modula page.

NoCforMe

... or learn how to find information on MSDN. Everything you need is there. Just need to do a little digging.
Assembly language programming should be fun. That's why I do it.