A bitwise operation transforms or combines an integer by working directly with its binary bits. Right shift (>>) moves bits toward lower positions, while logical AND (&) keeps selected bits and clears the rest. Together, these operations expose fields packed inside a value. section 5.7.1 section 5.8
Extracting fields from a CHIP-8 opcode
Treat the opcode 0x71E4 as four hexadecimal nibbles. Apply a mask to select each nibble, then shift it into the lowest position: c = (opcode & 0xF000) >> 12, x = (opcode & 0x0F00) >> 8, y = (opcode & 0x00F0) >> 4, and d = opcode & 0x000F. The resulting values are c = 0x7, x = 0x1, y = 0xE, and d = 0x4. Larger fields use the same idea: opcode & 0x0FFF extracts nnn, while opcode & 0x00FF extracts kk. section 5.7.1
Listing 5.21 Extracting variables from an opcode
fn main() {
let opcode: u16 = 0x71E4;
let c = (opcode & 0xF000) >> 12; #1
let x = (opcode & 0x0F00) >> 8; #1
let y = (opcode & 0x00F0) >> 4; #1
let d = (opcode & 0x000F) >> 0; #1
assert_eq!(c, 0x7); #2
assert_eq!(x, 0x1); #2
assert_eq!(y, 0xE); #2
assert_eq!(d, 0x4); #2
let nnn = opcode & 0x0FFF; #3
let kk = opcode & 0x00FF; #3
assert_eq!(nnn, 0x1E4);
assert_eq!(kk, 0xE4);
}
Inspect the complete Rust example and its assertions for extracting CHIP-8 opcode fields with masks and shifts. section 5.7.1
Bit operations are useful when manipulating the internals of data structures, decoding instructions, and working with values whose fields occupy fixed bit ranges. Because direct manipulation can be highly unsafe, verify masks, shifts, and integer widths carefully. section 5.8





