Masks: Why?

N

noridotjabi

I have often times seen masks used in C source code. I really don't
understand the purpose or functionality of this. I have seen used:

#define MASK 0x77

....

if(hello & MASK)

Also I don't (yes still don't) understand the purpose of the bitwise
operators. I understand there are times when you may pass to a
function:

func(ONE | TWO | THREE);

To pass those three options. What I don't understand is what that
means, what it is doing, and how the function knows that you passed
ONE, TWO, and THREE and not some value just equal to ONE | TWO | THREE
and another thing is what if ONE | THREE == TWO | FOUR. What then?
Mainly I just don't understand WHY a mask would be used, or why a
bitiwise operator would be used. I'm pretty sure I understand what a
bitwise operator does I just don't know why you would EVER need that
done. Thanks in advanced to anyone who helps someone who is thoroughly
confused.
Nori
 
V

Vladimir Oka

I have often times seen masks used in C source code. I really don't
understand the purpose or functionality of this. I have seen used:

#define MASK 0x77

...

if(hello & MASK)

Also I don't (yes still don't) understand the purpose of the bitwise
operators. I understand there are times when you may pass to a
function:

func(ONE | TWO | THREE);

To pass those three options. What I don't understand is what that
means, what it is doing, and how the function knows that you passed
ONE, TWO, and THREE and not some value just equal to ONE | TWO | THREE
and another thing is what if ONE | THREE == TWO | FOUR. What then?
Mainly I just don't understand WHY a mask would be used, or why a
bitiwise operator would be used. I'm pretty sure I understand what a
bitwise operator does I just don't know why you would EVER need that
done. Thanks in advanced to anyone who helps someone who is thoroughly
confused.

I'd still say you don't have a good grasp on bit representation of
values. I suggest you go back to some textbooks covering that.

Bitwise operators, and masks, are used to get/set/test individual bits
in a multi-bit value. Most often, these bits represent various flags
(e.g., if bit 5 is set, your MP3 player will be in repeat mode). Other
times, several values are packed into the same multi-bit field. A good
example is storage format of floating point numbers. Quite often (and I
am probably oversimplifying), they will be packed into a field not
unlike this: 1 bit for the sign of the mantissa, N bits for the value
of the mantissa, 1 bit for the sign of the exponent, M bits for the
value of the exponent.

Hope this clarifies things a bit.
 
C

Chris Dollin

I have often times seen masks used in C source code. I really don't
understand the purpose or functionality of this. I have seen used:

#define MASK 0x77

...

if(hello & MASK)

Also I don't (yes still don't) understand the purpose of the bitwise
operators.

To read or write a bit or groups of bits in a value without the other
bits being interfered with or interfering, and to do so efficiently.

It lets you represent (small) sets of values with machine integers.
I understand there are times when you may pass to a
function:

func(ONE | TWO | THREE);

To pass those three options. What I don't understand is what that
means,

If func expects a set of options, and ONE, TWO, and THREE are values
that represent (independant) sets of options (typically a single one
each), then the call says to take the /union/ of those sets -- ie all
the values -- and pass that to func.
what it is doing, and how the function knows that you passed
ONE, TWO, and THREE and not some value just equal to ONE | TWO | THREE

It doesn't, and it doesn't matter either.
and another thing is what if ONE | THREE == TWO | FOUR. What then?

Then the designer may be berated for a silly choice of values. Or
not, if it doesn't matter.
Mainly I just don't understand WHY a mask would be used, or why a
bitiwise operator would be used. I'm pretty sure I understand what a
bitwise operator does I just don't know why you would EVER need that
done.

Think of the value as a bunch of bits (which, by coincidence, is what
they are in most machines), each with its own specific meaning. Let's
say

enum { READ = 0x1, WRITE = 0x2, EXECUTE = 0x4 };

If bit 0 is set, we mean "allow reads" (of something, say files in a filing
system, or pages in a memory map), if bit 1 is set we mean "allow writes",
and if bit 2 is set we mean "allow execution".

If you want to test the read bit:

if (value & READ) readBitSet(); else readBitUnset();

The masking means that you /don't care/ about the WRITE and EXECUTE bits.

Similarly

value = value | WRITE; /* or value |= WRITE */

will switch on the WRITE bit (or leave it set, if it were set already)
/without changing/ the READ and EXECUTE bits. And

value = value & ~EXECUTE; /* or value &= ~EXECUTE */

will switch /off/ the EXECUTE bit (or leave it off, if it were off
already) without touching the others.

There are generalisations for when the values aren't just single bits.
For example, if you want to describe a node in a syntax tree, you
might use a single byte with five bits for its type and three for
its length [1] and then

thatByte & 0x7

will get you the length field (assuming you stored it at the low end)
and

thatByte & 0xf8

will get you the type field - which you may or may not want to shift
down.

[1] Of course you need to cope with long nodes somehow, eg by chaining.
 
?

=?ISO-8859-1?Q?Erik_Wikstr=F6m?=

I have often times seen masks used in C source code. I really don't
understand the purpose or functionality of this. I have seen used:

#define MASK 0x77

...

if(hello & MASK)

This is used to pass only a "part" of hello, more specific all bits of
hello that are set that are also set in MASK.
Also I don't (yes still don't) understand the purpose of the bitwise
operators. I understand there are times when you may pass to a
function:

func(ONE | TWO | THREE);

To pass those three options. What I don't understand is what that
means, what it is doing, and how the function knows that you passed
ONE, TWO, and THREE and not some value just equal to ONE | TWO | THREE

It does not know this, the result is that it's one value that is passed,
and this value is the result of the |-operation applied to ONE, TWO and
THREE. Someplace in func there will be code like:

if (arg & ONE)
{
/* do something */
}

That will perform some operation if ONE was passed.
and another thing is what if ONE | THREE == TWO | FOUR. What then?

Trouble, the idea is that each of these masks will be different from the
others. Normally there will only be one bit set for each mask. For
example ONE might have the first bit set and all other unset, TWO have
the second set and all other unset and so on.
Mainly I just don't understand WHY a mask would be used, or why a
bitiwise operator would be used. I'm pretty sure I understand what a
bitwise operator does I just don't know why you would EVER need that
done.

Remember that one of the reasons that C was invented was to write an OS
in it, an OS have to deal with manipulating hardware and hardware often
use status-registers that have to be read or written. And these
registers generally use individual bits to signal status.

In many situations there is no reason to play around with individual
bits, using a a couple of normal int and setting them to 1 or 0 works
just as well and you get the benefit of naming each variable. However
for other uses such as some binary formats (compression comes to mind)
you have to be able to modify individual bits.

Erik Wikström
 
F

Fred Kleinschmidt

I have often times seen masks used in C source code. I really don't
understand the purpose or functionality of this. I have seen used:

#define MASK 0x77

...

if(hello & MASK)

Also I don't (yes still don't) understand the purpose of the bitwise
operators. I understand there are times when you may pass to a
function:

func(ONE | TWO | THREE);

To pass those three options. What I don't understand is what that
means, what it is doing, and how the function knows that you passed
ONE, TWO, and THREE and not some value just equal to ONE | TWO | THREE
and another thing is what if ONE | THREE == TWO | FOUR. What then?

That means that whoever designed the values did a poor job.
Mask values can be defined in many ways, but should always be
such that only one bit is set. So:
#define ONE 1
#define TWO 2
#define THREE 4
#define FOUR 8

Anopther way:
#define ONE 1
#define TWO (1<<1)
#define THREE (1<<2)
etc.

Then ytou can use one parameter to specify that several options are
to be used. For example,
x = ONE | THREE | SEVEN
could be used to say that options 1, 3, and 7 should be performed:

if ( x & ONE ) {
/* perform otpion 1 */
}
if ( x & TWO ) {
/* perform option 2 */
}
etc.
 
J

John Devereux

Fred Kleinschmidt said:
That means that whoever designed the values did a poor job.
Mask values can be defined in many ways, but should always be
such that only one bit is set. So:
#define ONE 1
#define TWO 2
#define THREE 4
#define FOUR 8


Actually it is quite common to have "masks" defined with *groups* of
bits being set. For example an 8 bit hardware register might be layed
out as

aaabbbcc

Where aaa and bbb are 3 bit integers, and cc is 2 bits, representing
some hardware setting. Say aaa=speed_1, bbb=speed_2,
cc=direction.

Then you might do

unsigned char* reg = (unsigned char*) REGISTER_ADDRESS;
unsigned speed_1, speed_2, dir;

...

assert(speed_1<8 && speed_2<8 && dir<4);
reg = speed_1<<5 | speed_2<<2 | dir;

To adjust a single item, say speed_1, you then need a bitmask with
several bits set:


reg = reg & ~(7<<5) | speed1<<5;

The same applies to bitmasks being used to pack values into an integer
e.g. to save storage space, or to implement a binary protocol.
 
R

Roberto Waltman

Chris Dollin said:
I have often times seen masks used in C source code. I really don't
understand the purpose or functionality of this. I have seen used:

#define MASK 0x77
...
if(hello & MASK)

Also I don't (yes still don't) understand the purpose of the bitwise
operators.

To read or write a bit or groups of bits in a value without the other
bits being interfered with or interfering, and to do so efficiently.
....
Mainly I just don't understand WHY a mask would be used, or why a
bitiwise operator would be used. I'm pretty sure I understand what a
bitwise operator does I just don't know why you would EVER need that
done.

Think of the value as a bunch of bits (which, by coincidence, is what
they are in most machines), each with its own specific meaning. Let's
say

enum { READ = 0x1, WRITE = 0x2, EXECUTE = 0x4 };

If bit 0 is set, we mean "allow reads" (of something, say files in a filing
system, or pages in a memory map), if bit 1 is set we mean "allow writes",
and if bit 2 is set we mean "allow execution".

If you want to test the read bit:

if (value & READ) readBitSet(); else readBitUnset();

The masking means that you /don't care/ about the WRITE and EXECUTE bits.

Similarly

value = value | WRITE; /* or value |= WRITE */

will switch on the WRITE bit (or leave it set, if it were set already)
/without changing/ the READ and EXECUTE bits. And

value = value & ~EXECUTE; /* or value &= ~EXECUTE */

will switch /off/ the EXECUTE bit (or leave it off, if it were off
already) without touching the others.

There are generalisations for when the values aren't just single bits.
For example, if you want to describe a node in a syntax tree, you
might use a single byte with five bits for its type and three for
its length [1] and then

thatByte & 0x7

will get you the length field (assuming you stored it at the low end)
and

thatByte & 0xf8

will get you the type field - which you may or may not want to shift
down.

You will find bit masks very frequently in embedded code, were
individual bits in peripheral registers or output ports control
hardware functions.

As an exercise, think how you could solve the following:

Write a program to control the traffic lights at a street
intersection. Use the following definitions:
( Many,many necessary details omitted ... )


/* Input/Output port controlling the lights */
volatile unsigned char * const LIGHT_CTRL =
(volatile unsigned char * const) 0xABCD;

/* Individual light definitions */
#define NS_RED 0x01U /* North-South red lights */
#define NS_YELLOW 0x02U /* North-South yellow lights */
#define NS_GREEN 0x04U /* North-South green lights */
#define EW_RED 0x08U /* East-West red lights */
#define EW_YELLOW 0x10U /* East-West yellow lights */
#define EW_GREEN 0x20U /* East-West green lights */
#define NS_BUTTON 0x40U /* North-South pedestrian request button */
#define EW_BUTTON 0x80U /* East-West pedestrian request button */


void light_on(unsigned char const light)
{
*LIGHT_CTRL |= light;
}

void light_off(unsigned char const light)
{
*LIGHT_CTRL &= ~light;
}

unsigned int pedestrian_request(unsigned char const button)
{
return !!(*LIGHT_CTRL & button);
}

void go_north_south()
{
light_off(NS_RED | NS_YELLOW | EW_GREEN | EW_YELLOW);
light_on (NS_GREEN | EW_RED);
}
....



[1] Of course you need to cope with long nodes somehow, eg by chaining.
 
S

spibou

As a realistic example where masks would be not just useful but
essential is a chess programme which uses bitboards to represent
the chess board. Crafty comes to mind.
 
N

Nelu

As a realistic example where masks would be not just useful but
essential is a chess programme which uses bitboards to represent
the chess board. Crafty comes to mind.

Not sure if you've been told this before, but could you
be so nice as to quote something from
the posts you are replying to?
Although your post makes it as an interesting idea by itself
I think it's a followup to some other post, though.

Thank you.
 
S

spibou

Nelu said:
Not sure if you've been told this before, but could you
be so nice as to quote something from
the posts you are replying to?
Although your post makes it as an interesting idea by itself
I think it's a followup to some other post, though.

Thank you.

I wasn't replying to any specific post ; I was simply addressing the
general
topic of the thread. Is there any appropriate quoting to be made in
such a
case ?

Spiros Bousbouras
 
N

Nelu

I wasn't replying to any specific post ; I was simply addressing the
general
topic of the thread. Is there any appropriate quoting to be made in
such a
case ?
Then "Although your post makes it as an interesting idea by itself"
probably applies. But you could have quoted the question from
the OP, nonetheless. Not all the time, the subject matches the
content. Sometimes the OP sets a subject that has nothing in common
with the question. If you quote the question is much clearer that
you are talking about the same thing as the OP.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top