Please help unpack and PACK the data in WORD / DWORD

Started by BytePtr, December 13, 2009, 12:03:55 AM

Previous topic - Next topic

BytePtr

Thanks alot dedndave  and Steve.

But what is the reverse of this? I know how the values are saved now but how to get the values from them?
Pure "bitwork" now ? SHR'ing and other such things?

dedndave

that is fairly simple
to convert from decimal to file format:
i would remove the decimal (255.7 -> 2557), multiply it by 16384 (SHL 14), then divide by 10 and round (add one if remainder >4)
ater you are done rounding, you will want to compare the result to the max of 3FECCCh, and set the max if over

BytePtr


dedndave


        mov     eax,Decimal_Value_x10          ;2557 max
        shl     eax,14
        xor     edx,edx
        mov     ecx,10
        div     ecx
        cmp     edx,ecx
        cmc
        adc     eax,0
        cmp     eax,3FECCDh                    ;max result + 1
        cmc
        sbb     eax,0                          ;result in eax

well, that's one way - lol

BytePtr

Yep this works. Thanks.

But now final thing.


Getting real values from the bits saved in file.
Example:
App saved 51.4. Result is 0CD99 in hex. This hex value is in file now.

Let's say i need to get that value: 51.4 from the file.


How that should be done?


Pretty much of it probably would be reverse of the saving the bits? But i am sure that something else must be done.
To get the real values from the HEX again.


Drop me at least some algorithm and i will try code that. I will learn something from it that way.

dedndave

assuming you want an ASCII decimal string...
the result is little-endian (AL = first digit)
you will have to add the decimal point in, yourself (decimal point = 2Eh)

        mov     eax,Value_From_File            ;3FECCCh max
        mov     edx,10
        mul     edx                            ;edx becomes 0
        shr     eax,14
        adc     eax,edx                        ;2557 max result
        mov     ecx,100
        div     ecx
        aam
        bswap   eax
        mov     ax,dx
        aam
        xchg    al,ah
        or      eax,30303030h                  ;make it ASCII numeric

dedndave

oops - i think i re-arranged the digits   :bg
let's try that again...

        mov     eax,Value_From_File            ;3FECCCh max
        mov     edx,10
        mul     edx                            ;edx becomes 0
        shr     eax,14
        adc     eax,0                          ;2557 max result
        mov     ecx,100
        div     ecx
        aam
        xchg    eax,edx
        aam
        bswap   eax
        mov     al,dh
        mov     ah,dl
        or      eax,30303030h                  ;make it ASCII numeric

BytePtr

Well, this piece of code:
mov     eax,0160h            ;3FECCCh max
        mov     edx,10
        mul     edx                            ;edx becomes 0
        shr     eax,6


works and returns me the correct value without "dot". I changed shr eax, 14 to shr eax,

6

The rest of it doesn't work for me.

I haven't used ASM for a while now and seems that i have forgot many things. Now i am trying to get my hands again on it.

You said ASCII numeric string. You stored these 2 number in AL and AH?
And now they are represented as ASCII characters?


Correct? Why i am unable to display them then?

dedndave

well - shr eax,6 does not do the same thing as shr eax,14 - lol
look at my previous posts - i did update that last routine, as i made a mistake first time around   :bg
the result is 4 ASCII numeric characters in eax, the left-hand digit is in AL, second in AH, and so on
i did not supress leading zeros or place the decimal - i leave that stuff to you

BytePtr

I know that changing  shr 14 to shr 6 doesn't do the same thing.
Don't think that im so noob in asm.

Im not, just haven't used asm for a while now and forgot many things.


I changed it to shr 6 because this way the snippet
mov     eax,0160h            ;3FECCCh max
        mov     edx,10
        mul     edx                            ;edx becomes 0
        shr     eax,6


worked for me fine then. The rest of your code makes ASCII out of the numbers?

Correct?


Now i used your fixed code as is and messed around with it.

First i put 0660h (25.5) into EAX and then tried to print out the value:

mov     eax,0660h            ;3FECCCh max
        mov     edx,10
        mul     edx                            ;edx becomes 0
        shr     eax,14
          adc     eax,0                          ;2557 max result
          mov     ecx,100
          div     ecx
          aam
          xchg    eax,edx
          aam
          bswap   eax
          mov     al,dh
          mov     ah,dl
          or      eax,30303030h                  ;make it ASCII numeric

print str$(eax),13,10


Result is 825241648. Are they ASCII numeric character codes?
Or im heading in totally wrong way?


If i just: "print eax, 13,10" then program crashes.



13,10 (CR,LF) is not needed but im using them alot.

dedndave

well - part of the code converts the value to a binary number from 0 and 2557
we multiply by 10, then shift right 14 bits to divide by 16384
at the end of that shift, we round the result with adc eax,0
if the highest bit that was shifted off is a 1, it increments the result
if the highest bit that was shifted off is a 0, it does not increment the result

        mov     eax,Value_From_File            ;3FECCCh max
        mov     edx,10
        mul     edx                            ;edx becomes 0
        shr     eax,14
        adc     eax,0                          ;2557 max result

the next part splits that binary value into 4 seperate decimal digits

        mov     ecx,100
        div     ecx
        aam
        xchg    eax,edx
        aam
        bswap   eax
        mov     al,dh
        mov     ah,dl

at that point, there are 4 binary digits in EAX, each one in a seperate byte
the first digit is in AL (high order digit)
if you just want to store the 4 binary digits

        mov dword ptr Stored_Bytes,eax         ;Stored_Bytes is 4 bytes

if you want them to be ASCII numeric digits

        or      eax,30303030h                  ;make it ASCII numeric
        mov dword ptr Stored_Bytes,eax

the problem you are having with the print macro is that "print eax" displays the zero-terminated string at the address in eax
if you want to see what is in eax, try this...

Stored_Bytes db 4 dup(?),13,10,0
.
.
        or      eax,30303030h                  ;make it ASCII numeric
        mov dword ptr Stored_Bytes,eax
        print offset Stored_Bytes

if you want to view it in hexidecimal, this will work

        print   uhex$(eax),13,10

the uhex$ macro creates the zero-terminated string and passes its address to the print macro

BytePtr

Ohh, "offset", "dword ptr" all that stuff. Of course. Totally forgot them.
I used them in my 16bit asm programs.


Will take my fat asm books from my bookshelf and will read them again.


Seems that i forgot alot of important stuff.


Thanks Dave.

I will let you know how it goes.

BytePtr

dedndave or anybody.
I need your help again.

Let's say i have a 3 values like: (0.0, 2.0, 2.0)
In file, this is 2.0 saved like 0x8000, as hex.


The tool generates a .tmp file with values like these: (0,131072,131072)

What this could mean? They should be DWORD's, but im not sure.
I really would like to know, what they mean, is it possible to figure out, how is 2.0 related to 131072?

The numbers are fixed point always. Not floating.

Thanks.

qWord

Quote from: BytePtr on October 15, 2011, 01:13:22 PMI really would like to know, what they mean, is it possible to figure out, how is 2.0 related to 131072?
131072 = 0x20000
Maybe: 16 Bit for pre-decimal point positions and 16 bit for decimal places?
<0x2>.<0x0000>f
FPU in a trice: SmplMath
It's that simple!

dedndave

yah - you really haven't given us enough information to work with
there are many possible formats the might store 2.0 as 8000h