Question

I am trying to convert fat16 hex to get time hr:min:sec,I am getting hour and minutes right but I am having trouble with seconds.

first 5 bits is hour, next six bits are minutes, and the last 5 bits are seconds(result times 2)...

so if I enter a fat16 hex 0154 it is supposed to give me 10 hours, 32 minutes and 2 seconds, but I am not sure how to get seconds ? If I shift left for seconds how I am supposed to times it by 2 ?

this is what I have

INCLUDE Irvine32.inc
.data

        vFAT16 BYTE "Enter FAT16 to convert: " ,0
        vTIme BYTE "--:--:--" ,0

.code
main PROC
    ;--------- Enter Code Below Here

            call Clrscr





;-------------------------

        mov dh, 11
        mov dl, 0
        call Gotoxy

        mov edx, OFFSET vFAT16
        call WriteString

;-------------------------

        mov dh, 12
        mov dl, 0
        call Gotoxy

;-------------------------

        call ReadHex
        ror ax, 8
        mov ecx, eax

        and ax, 1111100000000000b
        shr ax, 11
        mov bh, 10
        div bh
        add ax, 3030h

        mov word ptr [vTime+0], ax
        mov eax, ecx


        and ax, 0000011111100000b
        shr ax, 5
        mov bh, 10
        div bh
        add ax, 3030h

        mov word ptr [vTime+3], ax

        and ax, 0000000000011111b
        shl ax, 11
        mov bh, 1
        div bh
        add ax, 3030h

        mov word ptr [vTime+6], ax




        mov edx, offset vTime
        call Writestring

        xor ecx, ecx
        call ReadString


    exit
main ENDP

END main
Was it helpful?

Solution

Ok, after re-reading, edit... So you need to multiply the seconds by 2, after using and to mask out the extra bits. You could use mul, but multiplying by two (or any power of 2) can be done with shift left (same as division by any power of 2 can be done by shifting right).

So, simply use shl ax, 1 for seconds. This multiplies ax by 2, which is what you want.

You are also missing the mov eax, ecx before processing seconds.

Then convert to 2 ASCII decimal digits same way as with minutes or hours. That means, you still need to divide by 10 when you convert seconds to 2 decimal digits, not by 1 as in the code (I mean, division by 1 does nothing...).

The 10 there is for conversion to decimal, not for something else. And it works, because you get the result of division in AL, and remainder in AH. And when you add 0x3030 to AX, you actually add 0x30 to AH and 0x30 to AL, and 0x30 is ASCII code of '0', so number in range 0..9 gets converted into a character '0'...'9', both for AL and AH in one operation. And then, x86 is little endian CPU, which means, when you store AX, it first stores AL, and then AH, so you actually get the digits in right order in destination string without swapping AL and AH.

It's worth noting, that this works only as long as there is no overflow, that is initial value of AX is in range 0..99. If it is something else, you get garbage output.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top