The MASM Forum

General => The Campus => Topic started by: Glenn9999 on August 29, 2015, 05:14:48 AM

Title: SyncSafe Integers - Encoding
Post by: Glenn9999 on August 29, 2015, 05:14:48 AM
Something I've been struggling with is getting an ASM implementation of a synch safe integer encoding.   More or less on ID3V2 tags, it requires integers that are MSB with the 7th bit not in use on each byte.  For instance:

                 HEX              Enc             Dec
255020    002CE403 000F482C  002CE403

I had the idea to shift on each part, but in research, I found this nice solution by dedndave from one of the old MASM forums.  Only thing that it was missing was the MSB thing, which I fixed.


function size_decodeh2(insize: DWord): DWord;
  // dedndave masm32
    asm
      bswap eax
      mov ecx,eax

      shl al,1
      shl ax,1
      shl eax,1
      and eax,00FFFFF8h   // don't understand what this does?

      and ecx,7F000000h
      or  eax,ecx
      shr eax,3
    end;


Other than the line I marked, I understand this fully.  However, I'm trying to encode, which seems to be doable if I reverse this logic, but I'm not having much luck coming up with the algo to do it.  Any thoughts or hints?
Title: Re: SyncSafe Integers - Encoding
Post by: dedndave on August 29, 2015, 07:08:46 AM
that line clears the high byte of EAX
i don't remember writing that code - lol
maybe you could link us to the original post ?

oh - i found it
Title: Re: SyncSafe Integers - Encoding
Post by: FORTRANS on August 29, 2015, 07:11:51 AM
Hi,

   The line you marked clears the high byte so it can be retrieved
from ECX with the next two lines.

QuoteHowever, I'm trying to encode, which seems to be doable if I reverse this logic, but I'm not having much luck coming up with the algo to do it.  Any thoughts or hints?


   Maybe something like the following?

; Enter with value in EAX.
        SHL     EAX,3
        MOV     ECX,EAX         ; Save "high" byte.
        AND     ECX,0FF000000H  ; Only high byte is good.
        AND     EAX,000FFFFFFH  ; High byte is in ECX.
        SHR     EAX,1
        OR      ECX,EAX         ; Save Next byte.
        AND     ECX,0FFFF0000H  ; Two high bytes good.
        AND     EAX,00000FFFFH  ; High bytes in ECX.
        SHR     EAX,1
        OR      ECX,EAX         ; Save Next byte.
        AND     ECX,0FFFFFF00H  ; Three high bytes good.
        AND     EAX,0000000FFH  ; High bytes in ECX.
        SHR     EAX,1
        OR      EAX,ECX         ; Retrieve high bytes.
        BSWAP   EAX


HTH,

Steve N.
Title: Re: SyncSafe Integers - Encoding
Post by: Glenn9999 on August 29, 2015, 07:15:11 AM
Quote from: dedndave on August 29, 2015, 07:08:46 AM
maybe you could link us to the original post ?

http://www.masmforum.com/board/index.php?topic=14509.0

Quote from: dedndave on August 29, 2015, 07:08:46 AM
that line clears the high byte of EAX

I knew that, but didn't see where it fit in on the algo.  Now that I see that in writing and think on it, I see how it fits now.
Title: Re: SyncSafe Integers - Encoding
Post by: Glenn9999 on August 31, 2015, 07:03:38 AM
Now that I got my mind wrapped around it, I saw I had a misunderstanding about what one of the assembler instructions does to the registers.  I ended up finishing the encoding piece the original way I had in mind.   It seems to work properly in my testing code and benchmarks well.  Sharing here:


function size_encodeh3(insize: DWord): DWord;
// by Glenn9999 with ideas stemming from this thread.
    asm
      SHL    EAX, 3
      MOV    ECX, EAX
      AND    ECX, $FF000000
      AND    EAX, $00FFFFFF
      SHR    EAX, 1
      OR     EAX, ECX
      SHR    AX, 1
      SHR    AL, 1
      BSWAP  EAX
    end;


Thanks for all the help!
Title: Re: SyncSafe Integers - Encoding
Post by: Donkey on September 01, 2015, 10:37:08 AM
I wrote one a long time ago, not very efficient but I wasn't too concerned as it is not a bottleneck since it is only used in the tag reader. It was pretty much a hack that I never bothered to fix up. (GoAsm syntax)

DecodeSynchSafe FRAME SSVAR
LOCAL SSCF1 :B
LOCAL SSCF2 :B
LOCAL SSCF3 :B
LOCAL SSBYTE1 :B
LOCAL SSBYTE2 :B
LOCAL SSBYTE3 :B
LOCAL SSBYTE4 :B

mov eax,[SSVAR]

mov [SSBYTE4],al
mov [SSBYTE3],ah
bswap eax
mov [SSBYTE1],al
mov [SSBYTE2],ah

mov al,[SSBYTE2]
mov [SSCF1],al
and B[SSCF1],1
shl B[SSCF1],7

mov al,[SSBYTE3]
mov [SSCF2],al
and B[SSCF2],3
shl B[SSCF2],6

mov al,[SSBYTE4]
mov [SSCF3],al
and B[SSCF3],7
shl B[SSCF3],5

; Build Bytes from data
;
mov al,[SSCF1]
or [SSBYTE1],al

shr B[SSBYTE2],1
mov al,[SSCF2]
or [SSBYTE2],al

shr B[SSBYTE3],2
mov al,[SSCF3]
or [SSBYTE3],al

shr B[SSBYTE4],3

; Build DWORD from bytes
;
mov al,[SSBYTE1]
mov ah,[SSBYTE2]
bswap eax
mov al,[SSBYTE4]
mov ah,[SSBYTE3]
bswap eax

ret
ENDF