Bin2Time: Unsigned milliseconds to time format hhh:mm:ss.sss

Tight_Coder_Ex 0 Tallied Votes 210 Views Share

I use GetTickCount in a lot of my applications, so I built this snippet to convert to hours minutes and seconds. Leading extraneous data is excluded from output.

Entry	ECX = Unsigned value of duration in milliseconds
	EDX = Pointer to ASCII output.

 Divisors		dd	3600000, 60000, 1
  
  HrsFmt		db	'%d:', 0
  MinFmt		db	'%02d:', 0
  SecFmt		db	'%06d', 0
  Formats		dd	HrsFmt, MinFmt, SecFmt

    0    57            push    edi
    1    56            push    esi
    2    53            push    ebx

	; Epilog set up for applications loop

    3    52            push    edx			; Preserve initial value
    4    BE <->        mov     esi, Divisors
    9    8BFA          mov     edi, edx
    B    BB <->        mov     ebx, Formats
    10   8BD1          mov     edx, ecx
    12   33C9          xor     ecx, ecx
    14   880F          mov     [edi], cl		; Nullify previous contents
    16   B1 03         mov     cl, 3
    18   51            push    ecx

    19   AD            lodsd				; Get next divisor
    1A   8BC8          mov     ecx, eax
    1C   8BC2          mov     eax, edx
    1E   33D2          xor     edx, edx
    20   F7F9          idiv    ecx
    22   8BC8          mov     ecx, eax
    24   87F3          xchg    ebx, esi
    26   AD            lodsd				; Get pointer to next format string
    27   87F3          xchg    ebx, esi
    29   23C9          and     ecx, ecx
    2B   75 05         jnz     32			; Was quotient null
    2D   803F 00       cmp     byte ptr [edi], 0	; Has anything been written to output
    30   74 0F         je      59

Write next segment of string with applicable format

    32   52            push    edx
    33   51            push    ecx
    34   50            push    eax 
    35   57            push    edi
    36   E8 <->        call    wsprintf			; Make this segment of string
    3B   83C4 0C       add     esp, 0C
    3E   5A            pop     edx
    3F   03F8          add     edi, eax
    41   59            pop     ecx
    42   E2 D4         loopd   19

The last part of output always has 6 characters and positions 1 & 2 must be moved to 0 & 1 and 2
replaced with the decimal point
    		   					
    44   8BCF          mov     ecx, edi
    46   2BF8          sub     edi, eax
    48   66:8B47 01    mov     ax, [edi+1]
    4C   66:AB         stosw
    4E   C607 2E       mov     byte ptr [edi], 2E
    51   5F            pop     edi
    52   2BCF          sub     ecx, edi
    54   803F 30       cmp     byte ptr [edi], 30
    57   75 0A         jnz     63

The possibility that either hours or seconds can have a leading zero and they must
be removed from output by shifting everything upward by 1

    59   8BF7          mov     esi, edi
    5B   51            push    ecx
    5C   57            push    edi
    5D   46            inc     esi
    5E   F3:A4         rep     movsb
    60   5F            pop     edi
    61   59            pop     ecx
    62   49            dec     ecx

Epilog 	ECX = Number of characters in output
	EDX = Unchanged, pointer to ASCII string

    63   8BD7          mov     edx, edi
    65   33C0          xor     eax, eax
    67   5B            pop     ebx
    68   5E            pop     esi
    69   5F            pop     edi
    6A   C3            ret

    6B   =	107 bytes
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.