Example 2: Hints on Using Bitmasks

In building your assembler and your simulator for Project 1 (and later projects as well), you will often need to look at only a portion of an integer -- to pull out a selected group of bits, ignoring all the rest. For instance, if you want a 3-bit field in an instruction that identifies a register number, you will not want the surrounding bits.

This is done using bitmasks, or just masks. A mask is a field of bits that corresponds to the number of bits that you want to pull out of the integer. You shift either the instruction or the mask over to the appropriate place and perform an and to extract the desired bits; I will demonstrate this in a moment.

First, here is a table that you can use; it shows a bit pattern and the corresponding hexadecimal number that you would use to create the mask.

	#Bits	Bit Pattern	Hexadecimal Number
	1	1		0x1
	2	11		0x3
	3	111		0x7
	4	1111		0xf
	5	11111		0x1f
	6	111111		0x3f
	7	1111111		0x7f
	8	11111111	0xff
	9	111111111	0x1ff
	10	1111111111	0x3ff
	11	11111111111	0x7ff
	12	111111111111	0xfff
... and so on.

How do you use this? Very simple. If you want to extract a field from an integer called, for instance, "instruction", and place it into the variable "field", you would do the following. Say that you want a three-bit field from bit 12 to bit 14, assuming that the first bit is bit 0.

	field = (instruction >> 12) & 0x7;
This shifts the bits in "instruction" down by 12 bits, then uses a mask to zero out everything but the bits in the lowest three places (bits 0-2). After the shift, bits 12-14 are in locations 0-2, so this is exactly what we want.

Bits 8-11:

	field = (instruction >> 8) & 0xf;

Bits 2-7:

	field = (instruction >> 2) & 0x3f;

Bits 13-15:

	field = (instruction >> 13) & 0x7;
Now, suppose that you want to insert a field into the integer called "instruction". Let's say that you have an opcode value or a register value or something like that held in the variable "field" and you want to put it into the variable "instruction". Say that it is a 3-bit quantity and you want it in bits 10-12.
	instruction = (field & 0x7) << 10;
The and ensures that "field" contains a 3-bit number (by zeroing out any other bits), and the shift puts the three-bit field into place. The problem is that the variable "instruction" now contains only the three-bit field now in bits 10-12. In the general case, we would like to construct instructions out of many fields. Here is how.

Suppose we have a 3-bit opcode stored in the variable op, we have a 3-bit register stored in the variable r1, and we have another 3-bit register stored in the variable r2. Say we want them (respectively) in bits 15-13, 12-10, and 9-7. We would build up the instruction as follows:

	instruction = ((op & 0x7) << 13) | ((r1 & 0x7) << 10) | ((r2 & 0x7) << 7);
The ands ensure that each variable is only three bits wide, by masking out all other bits. The left-shifts put the values into place, according to the desired location. Since there is no overlap between the fields (we have ensured this by masking out any possible extra bits), the ors simply concatenate the fields together.


Written by Prof. Bruce L. Jacob, Electrical & Computer Engineering, University of Maryland.