How do I declare bits in a structure?

I want to translate the following C code:



struct MP3FRAMEHEADER
{
unsigned emphasis : 2; unsigned original : 1; unsigned copyright : 1; unsigned modeext : 2; unsigned chanmode : 2; unsigned privbit : 1; unsigned padding : 1; unsigned samplerate : 2; unsigned bitrate : 4;
unsigned hascrc : 1; unsigned mpeglayer : 2; unsigned mpegver : 2; unsigned framesync : 11;
};


The structure occupies 4 bytes.
Posted on 2002-06-08 22:14:34 by grv575
Example taken from windows.inc:


BITRECORD RECORD fBinary:1,fParity:1,fOutxCtsFlow:1, fOutxDsrFlow:1, fDtrControl:2,\
fDsrSensitivity:1, fTXContinueOnXoff:1, fOutX:1, fInX:1, fErrorChar:1,\
fNull:1, fRtsControl:2, fAbortOnError:1, fDummy2:17


Thomas
Posted on 2002-06-09 03:22:20 by Thomas
Sweet. Thx Thomas.
Posted on 2002-06-09 13:52:58 by grv575
I can't use records like in C?

In C I can declare a bit record

brecord
{
a : 1
b : 2
} br;

and then access the elements like a structure:

i = br.a;

Can I do this just as easily in asm? What I'm trying to do is access a packed record of bits directly without masking. Possible?

I'm assuming you can't. In that case how do you go about doing this with the MASK operator?
Posted on 2002-06-09 14:39:14 by grv575
If you want to use records (structures of packed bits fields) in asm it looks like what you have to do access each field is:

BITRECORD RECORD \
field1 : 1 ; 1 bit wide
field2 : 2 ; 2 bits wide
field3 : 11

rec BITRECORD <>

mov eax, rec
and eax, MASK field1
shr eax, field1

(Whereas in C you can access the fields directly)
Posted on 2002-06-10 16:23:01 by grv575
Hi grv575,
I think your method of accessing the bit fields is necessary only if you need to access elements of more than 1 bit in width.

For records where each element is a single bit it is much more effective to use direct bit access, with the opcodes: BT, BTS, BTR, BTC. According to my docs these allow direct access of each bit in huge bitmaps without first fetching the RAM words to any register.

For example:


mov eax,1023
lea edx,your_struct
btr [edx],eax


This code will access the 127th byte of your_struct, and in that byte it will read bit 7, copying it to the carry flag, and then that bit in ram will be cleared. This ability to index huge arrays of bits is really neat.

Just don't try it with immediate bit indexes, as those will be masked by an implicit '&0x1F'.
Posted on 2002-06-10 21:22:41 by RAdlanor
Doesn't seem like a lot of code these days does manipulation of individual bits. It's just a lot less work to access a byte or dword at a time than to pack & unpack bytes with shift/masking operations esp. with today's hardware.

I just needed a convenient way to parse mp3 frame headers. The structure is defined as:

MP3FRAMEHEADER record \
framesync : 11,
mpegver : 2,
mpeglayer : 2,
hascrc : 1,
bitrate : 4,
samplerate : 2,
padding : 1,
privbitv : 1,
chanmode : 2,
modeext : 2,
copyright : 1,
original : 1,
emphasis : 2

Unfortunately there is absolutely *no* documentation on the web about asm records.

What is strange is that
and eax, MASK rec.field1
works while
shr eax, rec.field1
does not.

There's no namespaces for the fields of a record, so I guess all the record fields have to be unique accross all your include files, which is why I bet they're not used frequently in masm.
Posted on 2002-06-10 22:23:39 by grv575