News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

BIT-stream how to manage?

Started by frktons, January 07, 2013, 08:46:47 PM

Previous topic - Next topic

frktons

I'm wondering if the MASM32 project already contains
some tools to manage BIT-Streams.
I mean if I want to read 4 BITs at a time, or 3, or 5,
do I have to read a byte and after playing with the bits
with the usual instructions [shr, ror, bit, test...]?
Or can I define some kind of structure to have groups of BITs
as sort of variables?

bitgroup type

    LowerBits BIT  3
    InterBits  BIT  2
    UpBits     BIT  3

bitgroup ends


Or whatever gives the possibility to manage groups of BITs
inside Bytes?


There are only two days a year when you can't do anything: one is called yesterday, the other is called tomorrow, so today is the right day to love, believe, do and, above all, live.

Dalai Lama


frktons

From what you said in the old forum, I've to deduce there is no standard
way to manage the task, and MASM hasn't a BIT field type, but has a RECORD
type that can do the task:
Quote
Here are two macros for using bitfields defined through RECORD. Usage:

FieldSet MyRec.SlotHigh, 11
print str$(FieldGet(MyRec.SlotHigh))


FieldGet MACRO SrcDotField ; trashes and returns eax
LOCAL is, src, field
  is INSTR <SrcDotField>, <.>
  if is eq 0
.err <*** source.field required ***>
  endif
  src SUBSTR <SrcDotField>, 1, is-1
  field SUBSTR <SrcDotField>, is+1
  ifdifi src, <eax>   
mov eax, src
  endif
  and eax, mask field
  if field
shr eax, field
  endif
  EXITM <eax>
ENDM

FieldSet MACRO SrcDotField, TheVal ; trashes and returns eax
LOCAL is, src, field
  is INSTR <SrcDotField>, <.>
  if is eq 0
.err <*** source.field required ***>
  endif
  src SUBSTR <SrcDotField>, 1, is-1
  field SUBSTR <SrcDotField>, is+1
  ifdifi <TheVal>, <eax>   
mov eax, TheVal
  endif
  if field
shl eax, field
  endif
  and src, not mask field
  add src, eax
ENDM


Examples:

MyRECORD RECORD SlotHigh:4, SlotMid:7, SlotLow:7, SlotRest:32-4-2*7 ; the order is high to low
.data
MyRec1 MyRECORD <1, 3, 7, 15>

.data?
MyRec MyRECORD <>
...
Print Str$("The value of MyRec1.SlotMid is\t%i\n", FieldGet(MyRec1.SlotMid))
Print Str$("The value of MyRec1.SlotLow is\t%i\n", FieldGet(MyRec1.SlotLow))

FieldSet MyRec.SlotHigh, 11
FieldSet MyRec.SlotMid, 12
FieldSet MyRec.SlotLow, 13
FieldSet MyRec.SlotRest, 14
Print Str$("The value of MyRec.SlotHigh is\t%i\n", FieldGet(MyRec.SlotHigh))
Print Str$("The value of MyRec.SlotMid is\t%i\n", FieldGet(MyRec.SlotMid))
Print Str$("The value of MyRec.SlotLow is\t%i\n", FieldGet(MyRec.SlotLow))
Print Str$("The value of MyRec.SlotRest is\t%i\n", FieldGet(MyRec.SlotRest))


For compact display, I have used the Print and Str$ macros from the MasmBasic library, but the FieldSet/FieldGet macros will work with standard Masm32, too.
There are only two days a year when you can't do anything: one is called yesterday, the other is called tomorrow, so today is the right day to love, believe, do and, above all, live.

Dalai Lama

mineiro

happy new year Sir's;

yes, PC family deals with bytes, to change one bit you should change 1 byte.
If the boolean mask is not static, you should maintain a counter.

qWord

What about using equates EQU/= for bit masks? - I think this common practice.
MREAL macros - when you need floating point arithmetic while assembling!

frktons

Quote from: mineiro on January 08, 2013, 01:02:08 AM
happy new year Sir's;

yes, PC family deals with bytes, to change one bit you should change 1 byte.
If the boolean mask is not static, you should maintain a counter.
Happy new year to you mineiro.

You mean if I have to use 4 BITs for each process, the mask
is static and there is no need for a (BIT) counter?
In a compression task this could be better than have to deal
with a counter as well, I presume, except for particular situations.

Quote from: qWord on January 08, 2013, 01:09:19 AM
What about using equates EQU/= for bit masks? - I think this common practice.
Hi qWord, probably you are right, I'm not accustomed with these
"masks stuff" very much.
If you have a working example to show me I could understand better.
There are only two days a year when you can't do anything: one is called yesterday, the other is called tomorrow, so today is the right day to love, believe, do and, above all, live.

Dalai Lama

qWord

MSK_BIT_0 EQU 00000001y
MSK_BIT_1_3 EQU 00001110y
MSK_BIT_4_7 EQU 11110000y

and/test/xor/or eax,MSK_BIT_1_3
...
.if value & MSK_BIT_4_7
...
.elseif value & (NOT MSK_BIT_0)
...
.endif

...
MREAL macros - when you need floating point arithmetic while assembling!

frktons

Quote from: qWord on January 08, 2013, 01:44:36 AM
MSK_BIT_0 EQU 00000001y
MSK_BIT_1_3 EQU 00001110y
MSK_BIT_4_7 EQU 11110000y

and/test/xor/or eax,MSK_BIT_1_3
...
.if value & MSK_BIT_4_7
...
.elseif value & (NOT MSK_BIT_0)
...
.endif

...

Thanks qWord, I think I got your point now, but with a
small doubt:

and/test/xor/or eax,MSK_BIT_1_3

Considering we are working on a BYTE at a time, shouldn't it
be:
and/test/xor/or al/ah,MSK_BIT_1_3
?

or in this case it works the same?
What happens to the rest of the dword?
There are only two days a year when you can't do anything: one is called yesterday, the other is called tomorrow, so today is the right day to love, believe, do and, above all, live.

Dalai Lama

mineiro

Quote from: frktons on January 08, 2013, 01:12:41 AM
You mean if I have to use 4 BITs for each process, the mask
is static and there is no need for a (BIT) counter?
yes, you can do that in 2 moment, deal with high nibble and after with the lower nibble.
lea esi,input
mov ecx,sizeof input
.while ecx != 0
movzx eax,byte ptr [esi]
ror eax,4
;high nibble in al, and/test/xor/or al,MSK_BIT_1_3

and al,0
rol eax,4
;lower nibble in al
dec ecx
.endw


I was in mind when posting before something like:
shld eax,edx,cl ;read cl bits of edx in eax

frktons

Quote from: mineiro on January 08, 2013, 08:38:21 AM
yes, you can do that in 2 moment, deal with high nibble and after with the lower nibble.
lea esi,input
mov ecx,sizeof input
.while ecx != 0
movzx eax,byte ptr [esi]
ror eax,4
;high nibble in al, and/test/xor/or al,MSK_BIT_1_3

and al,0
rol eax,4
;lower nibble in al
dec ecx
.endw


I was in mind when posting before something like:
shld eax,edx,cl ;read cl bits of edx in eax


Yes mineiro, the first method for fixed lenght mask,
and the second for variable lenght are surely doable.
I've to make some tests to see if in the long run of
a compression task these methods are fast enough
or I have to deal with larger bit-masks and elaborate
in parallel many symbols at the same time.
There are only two days a year when you can't do anything: one is called yesterday, the other is called tomorrow, so today is the right day to love, believe, do and, above all, live.

Dalai Lama