If you need to set bits, use or
If you need to clear bits, use and
If you need to set some bits and clear others, use one of each
- Each of our operators (and/or) has what we will call a dominant value.
- That is a value that, when composed with another value, yields itself.
- For or's the dominant value is 1 because (1 or x) = 1 for any x.
- For and's the dominant value is 0 because
(0 and x) = 0 for any x.
- Each of our operators (and/or) has what we will call a recessive value.
- That is a value that, when composed with another value, yields the other value.
- For or's the recessive value is 0 because
(0 or x) = x for any x.
- For and's the recessive value is 1 because
(1 and x) = x for any x.
- You can use truth tables to verify all of this.
Here is a diagram showing a 32-bit value in $t0 with asterisks
in the bits we need to set or clear: 2, 9, 13, 21
It also shows the binary masks we would need to do the setting or clearing
The general rule is to use dominant values against the bits we need to set or clear
and recessive values against the bits we need to leave as they are
This general rule has two special cases: one for setting bits, and one for clearing bits
- For bits we need to set, we use or;
the mask will have dominant 1's where we need to set bits
and recessive 0's everywhere else.
- For bits we need to clear, we use and;
the mask will have dominant 0's where we need to clear bits and recessive 1's everywhere else.
- The diagram also has boxes that divide the bits into groups of 4.
- That helps us look at the diagram and read the masks in hexadecimal.
We need to be careful about the size of the mask
- If all the bits to be changed are in the green half of $t0 (i.e. if there were no * in bit 21),
we can use a 16-bit mask.
- In this case, the mask would be 0xDDFB for and;
it would be 0x2204 for or.
- So we would write one of the following:
- andi $t0 $t0 0xDDFB
- ori $t0 $t0 0x2204
- If there are bits to be changed in the yellow half
(i.e. as the diagram is), then we need a 32-bit mask.
- In this case, the mask would be 0xFFDFDDFB for and;
it would be 0x00202204 for or.
- So we would write them this way:
- andi $t0 $t0 0xFFDFDDFB
- ori $t0 $t0 0x00202204
- But MARS would assemble them this way, which might be a surprise at first:
- lui $at 0xFFDF
- ori $at $at 0xDDFB
- and $t0 $t0 $at
- - - - - - - - - - - - - - - - - - -
- lui $at 0x0020
- ori $at $at 0x2204
- or $t0 $t0 $at
- The first two instructions copy our entire 32-bit mask into $at.
- Then $at becomes the mask, and the R-format version of our and/or
is used against it to do the right thing.
- Decide whether to use and or or.
- Decide whether to use a 16-bit mask or a 32-bit mask.
- Write the dominant value next to the bits to be set or cleared.
- Write the recessive value next to the bits to be left as they are.
- This gives you the mask in binary.
- Convert the binary to hexadecimal for use in MIPS source code.