The MASM Forum Archive 2004 to 2012

General Forums => The Workshop => Topic started by: BytePtr on December 13, 2009, 12:03:55 AM

Title: Please help unpack and PACK the data in WORD / DWORD
Post by: BytePtr on December 13, 2009, 12:03:55 AM
Hi all. Haven't been here for a while.

There is a simple program that takes a real numbers and saves them to file.
By real numbers i mean numbers with dot, for example: 1.2, 3.4, 124.9 etc.

For example the input numbers are
1.0, 0.0, 0.0

When it writes them to file it packs them somehow or swaps and result is this:

00 00 40


If i do a: 40 shr 6 then i get correct value: 1 or anything else that is in that place.
Why 6? Because Bit-Set has 6 zeroes at the right.

Here is a shot:
(http://img187.imageshack.us/img187/2281/saving1.png) (http://img187.imageshack.us/i/saving1.png/)

When something else is used instead of zeroes at the right, for example:
1.2, 0.0, 0.0


Things get complicated, it saves this like so:
00 CC 4C

Here is a shot:
(http://img683.imageshack.us/img683/2042/shot2sav.png) (http://img683.imageshack.us/i/shot2sav.png/)


Im always watching that Bit-Set binary data in that window.

The problem is that i don't get it how it packs the numbers in that case?
Also it flips the bytes: it should be 4C CC which is 19660 in decimal and 01001100 11001100 in binary. Which is (16bit) 2 bytes (a WORD)

0.1 is saved like this: 66 06

Assembler gurus here, tell me how the real numbers are saved?

If i could at least pack the real numbers to get same bits then unpacking just would basically be reverse of this.
Something is probably ANDed, XORed and maybe ORed and then shifted.

I need to unpack the data and later again pack.

Any help is greatly appreciated.
Title: Re: Please help unpack the data in WORD
Post by: dedndave on December 13, 2009, 02:03:15 AM
i don't know if they are using intel standard real format - they may be (it would seem convenient)
i didn't evaluate the numbers you posted to see
but, here is a site that has the info...
http://www.ray.masmcode.com/tutorial/fpuchap2.htm
they look like they might be "real4" values - 4 byte reals
Title: Re: Please help unpack the data in WORD
Post by: raymond on December 13, 2009, 05:23:20 AM
Quotethey look like they might be "real4" values - 4 byte reals

That is impossible. The ".2" decimal fraction is not an exact multiple of fractional powers of 2 and bits would be set in all 4 consecutive bytes of a REAL4. His 1.2 would look more like 3F99999A according to the IEEE format of REAL4 floating points.

BytePtr must provide some additional information on what is generating those displayed numbers if he expects an answer.
Title: Re: Please help unpack the data in WORD
Post by: dedndave on December 13, 2009, 12:30:03 PM
well - that's what i said - i didn't take the time to evaluate the numbers he posted
but, the format may be similar - at least it gives him a place to start
the thing is, he has posted only a few values
to reverse-engineer the format would require several more values as examples
and, even then, you might not have it right
it shouldn't be all that hard to find the ms word file format defintion
keep in mind that the format may be from ms excel, instead - you may want to search for that file definition also
that could save you a lot of headaches and wasted effort
Title: Re: Please help unpack the data in WORD
Post by: BytePtr on December 13, 2009, 01:34:46 PM
Thanks for replies. The numbers above are just examples. User can use any number in range of 0.0 to 255.8
And it's not Excel or any such app.

It's a game scripting compiler tool that takes user scripts that parses them with Lexx or Yacc and generates compiled script.
Compiled scripts are always 80.7KB in size. This is what game uses.
And unfortunately the specs are not available. They were never released.

Seems that this compiler detects if number after dot is greater than 0, if it is then it uses some other methods to save the numbers and if the number after dot is 0 then it saves the real number as integer.
At least it seems so.


But the fact is: dot must always present in number. Otherwise compiler throws an error.
Title: Re: Please help unpack the data in WORD
Post by: FORTRANS on December 13, 2009, 01:48:54 PM
Hi,

   Plugging the (little endian) numbers in a calculator, it seems
that you have fixed point numbers, not floating point.  At least
they sure look that way, given the examples.

Regards,

Steve N.
Title: Re: Please help unpack the data in WORD
Post by: BytePtr on December 13, 2009, 01:51:42 PM
Yeah fixed point for sure.

I don't think that they made this so complex by using floating point. No.
The numbers after dot are just for adjusting, so they can handle things more precisely.
Title: Re: Please help unpack the data in WORD
Post by: dedndave on December 13, 2009, 02:02:50 PM
well - we don't call that "flipping" - lol
for us, it is normal for higher-order bytes of values to have higher addresses (called "little-endian", as opposed to "big-endian")
but - the 255.8 clue doesn't help much
the reason is, that could be stored as a 16-bit integer of 2558
that tells me that the format probably allows larger values than 255.8, and/or more than 2 decimal places (25580 also fits into 16 bits)
the problem you may have is describing special values like infinity, if it allows it and other special values
and - how does the program recognize whether it is stored as an integer or a real ?
the answer to that is: it is likely that the format is the same - i.e. values under 256 with no decimals just happen to be integers
if you look at Ray's tutorial i linked above, you will see some characteristics that may help you
that is, the general form in how real numbers are stored
in the case of intel reals, there is a sign bit, some number of exponent bits, and some number of mantissa bits
i do see a pattern with which i am familiar
that is the CCCCC pattern (in binary, that's ...110011001100...)
that pattern results when you divide a binary orthogonal (like 65536 or 4294967296) by 10
Title: Re: Please help unpack the data in WORD
Post by: BytePtr on December 13, 2009, 02:14:08 PM
It maybe allows larger values but they are never used.
Everything is limited to user. Nothing can be infinite in scripting, that's for sure. Scripting manual also tells that.
Otherwise game will crash and access violation occurs.
The game itself is limited to 256x256x8 area. The real numbers i posted are the coordinates.

I will try more different numbers and see what it generates from them.
Title: Re: Please help unpack the data in WORD
Post by: dedndave on December 13, 2009, 02:15:34 PM
in "4CCCh", the bit from the 4 may be the "1.0" part and the CCC bits may be the "0.2" part (2/10)

QuoteThe game itself is limited to 256x256x8 area.
well - there is more to it than that, if you have a number like 1.2 or 255.8, then the real grid is something like 2558 x 2558 x 78

perhaps they are storing the three coordiantes as seperate integers
Title: Re: Please help unpack the data in WORD
Post by: dedndave on December 13, 2009, 02:21:43 PM
you need to make a table of values

0.0
0.2
0.4
0.6
0.8
1.0
1.2
.
.
10.0
12.0

and so on - do enough decades until you see the pattern
Title: Re: Please help unpack the data in WORD
Post by: FORTRANS on December 13, 2009, 02:26:34 PM
Hi,

   To elaborate, given the examples:


  Given    Hex      Dec          Binary
   1.0 => 4000H => 16384 => 100110011001100B
   1.2 => 4CCCH => 19660 => 100000000000000B
   0.1 => 0666H =>  1638 =>     11001100110B

  You (apparently) have a fixed point number created by
multiplying a real number by 16384 and saving the integer
part.

HTH?

Steve
Title: Re: Please help unpack the data in WORD
Post by: dedndave on December 13, 2009, 02:27:55 PM
enter the maximum 3D coordinate 255.8, 255.8, 7.8 - or whatever it is
show us that representation

EDIT - looks like Steve is on the right track   :U
Title: Re: Please help unpack the data in WORD
Post by: BytePtr on December 13, 2009, 02:42:08 PM
(http://img502.imageshack.us/img502/1816/maximumbit.png) (http://img502.imageshack.us/i/maximumbit.png/) (http://img502.imageshack.us/img502/maximumbit.png/1/w798.png) (http://g.imageshack.us/img502/maximumbit.png/1/)

I entered. (255.7, 255.7, 7.7).
Because 0 is also used. So: 0-255 = 256 and 0-7 = 8.


Steve:
Well it seems that you are correct. I took one simple real number like 1.0 and multiplied it with the number: 1.0 * 16384 and really got the same value as in the compiled script.

But more tests must be done. To be sure. I will try more numbers. But i think that this is it.


Title: Re: Please help unpack the data in WORD
Post by: dedndave on December 13, 2009, 02:52:07 PM
yup - Steve got it - take the real, mul by 16384 and round to the nearest whole integer
Title: Re: Please help unpack the data in WORD
Post by: BytePtr on December 13, 2009, 02:59:40 PM
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?
Title: Re: Please help unpack the data in WORD
Post by: dedndave on December 13, 2009, 03:13:03 PM
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
Title: Re: Please help unpack the data in WORD
Post by: BytePtr on December 13, 2009, 03:14:13 PM
Thanks. I will try.

Will let you know.
Title: Re: Please help unpack the data in WORD
Post by: dedndave on December 13, 2009, 03:18:45 PM

        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
Title: Re: Please help unpack the data in WORD
Post by: BytePtr on December 13, 2009, 03:53:24 PM
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.
Title: Re: Please help unpack the data in WORD
Post by: dedndave on December 13, 2009, 04:04:33 PM
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
Title: Re: Please help unpack the data in WORD
Post by: dedndave on December 13, 2009, 04:40:32 PM
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
Title: Re: Please help unpack the data in WORD
Post by: BytePtr on December 13, 2009, 10:00:57 PM
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?
Title: Re: Please help unpack the data in WORD
Post by: dedndave on December 14, 2009, 12:06:13 AM
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
Title: Re: Please help unpack the data in WORD
Post by: BytePtr on December 14, 2009, 06:25:40 PM
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.
Title: Re: Please help unpack the data in WORD
Post by: dedndave on December 14, 2009, 08:35:48 PM
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
Title: Re: Please help unpack the data in WORD
Post by: BytePtr on December 14, 2009, 09:44:25 PM
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.
Title: Re: Please help unpack the data in WORD
Post by: BytePtr on October 15, 2011, 01:13:22 PM
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.
Title: Re: Please help unpack the data in WORD
Post by: qWord on October 15, 2011, 01:39:39 PM
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
Title: Re: Please help unpack the data in WORD
Post by: dedndave on October 15, 2011, 01:42:12 PM
yah - you really haven't given us enough information to work with
there are many possible formats the might store 2.0 as 8000h
Title: Re: Please help unpack the data in WORD
Post by: qWord on October 15, 2011, 01:47:10 PM
Quote from: dedndave on October 15, 2011, 01:42:12 PM2.0 as 8000h
131072 = 0x20000  :8)
Title: Re: Please help unpack the data in WORD
Post by: dedndave on October 15, 2011, 03:08:18 PM
maybe you can show us how more values are stored
can it be negative ? - show us how some negative values are stored
what is the maximum value ? - show us how that is stored
what is the minimum value ? - show us how that is stored
show us how 0.0, 0.5, 1.0, 1.5 are stored
Title: Re: Please help unpack the data in WORD
Post by: MichaelW on October 15, 2011, 05:28:56 PM
I did a quick test to see if the stored values might be half-precision floating-point numbers, but in that format 2.0 is 4000h.

http://en.wikipedia.org/wiki/Half_precision


Title: Re: Please help unpack the data in WORD
Post by: dedndave on October 15, 2011, 06:10:56 PM
it could be as simple as 2 bits ahead of the DP and 14 bits after

xx.xxxxxxxxxxxxxx

the range would be 0 to +3.99993896484375 (which is 3 + (16383/16384))
Title: Re: Please help unpack the data in WORD
Post by: BytePtr on October 15, 2011, 11:32:15 PM
Solved this problem, by using typecasting to "WORD" and "shr 16"
To get higher and lower values packed in DWORD.

I don't know why, but it worked for me.

I have alot to learn.
Title: Re: Please help unpack the data in WORD
Post by: raymond on October 16, 2011, 01:00:44 AM
QuoteThe numbers are fixed point always. Not floating.

If the "tool" he is using is the MixLib library for fixed point math ( http://www.ray.masmcode.com/fixmath.html ), he would be getting 20000h for 2.0. BytePtr was probably correct.
Title: Re: Please help unpack the data in WORD
Post by: BytePtr on December 13, 2011, 09:33:20 AM
Hi again all.
I have a DWORD32 (unsigned int). The value i will hold in this is maximum: 526271.
Also i would like to store single digit in it, just one of the: 0, 1, 2, 3, 4.

The big number max is 526271 as i said, but it changes (could be even 0), same with single small number, it could be anything from 0 to 4.


Is it possible somehow pack this info together and later also unpack the big number and this single digit, without data loss?
TIA
Title: Re: Please help unpack and PACK the data in WORD / DWORD
Post by: jj2007 on December 13, 2011, 10:14:05 AM
No problem...

include \masm32\MasmBasic\MasmBasic.inc   ; download (http://www.masm32.com/board/index.php?topic=12460)
   Init
   mov eax, 4   ; Factor A
   shl eax, 28
   mov ebx, 526271   ; Factor B
   or ebx, eax   ; A or B
   nop

   mov eax, ebx   ; read Factors
   sar eax, 28   ; shift out B
   Print Str$("Factor A=%i\n", eax)

   mov eax, ebx   ; read Factors
   and eax, 1111111111111111111111111111b   ; isolate A
   Print Str$("Factor B=%i\n", eax)

   Inkey "ok"
   Exit
end start

Factor A=4
Factor B=526271
Title: Re: Please help unpack and PACK the data in WORD / DWORD
Post by: BytePtr on December 13, 2011, 10:29:51 AM
I started to read this:
http://webmasters.physics.upatras.gr/mirrors/assembly/Page_AoA/4_5.pdf

And even tried to code out something, but not the way you did it.
I wish i could throw out code like this in a seconds.

Thanks alot jj2007. I will credit you for this.