¿Qué es el enmascaramiento de bits?

Soy bastante nuevo en la progtwigción C, y encontré un poco de enmascaramiento. ¿Puede alguien explicarme el concepto general y la función del enmascaramiento de bits? Los ejemplos son muy apreciados.

Una máscara define qué bits quiere conservar y qué bits quiere borrar.

Enmascarar es el acto de aplicar una máscara a un valor. Esto se logra haciendo:

  • AND en modo bit para extraer un subconjunto de los bits en el valor
  • OR de bit a bit para establecer un subconjunto de los bits en el valor
  • Bitwise XORing para alternar un subconjunto de los bits en el valor

A continuación se muestra un ejemplo de extracción de un subconjunto de los bits en el valor:

Mask: 00001111b Value: 01010101b 

Aplicar la máscara al valor significa que queremos borrar los primeros 4 bits (más altos) y mantener los últimos 4 bits (más bajos). Por lo tanto, hemos extraído los 4 bits más bajos. El resultado es:

 Mask: 00001111b Value: 01010101b Result: 00000101b 

El enmascaramiento se implementa con AND, por lo que en C obtenemos:

 uint8_t stuff(...) { uint8_t mask = 0x0f; // 00001111b uint8_t value = 0x55; // 01010101b return mask & value; } 

Aquí hay un caso de uso bastante común: Extraer bytes individuales de una palabra más grande. Definimos los bits de orden superior en la palabra como el primer byte. Usamos dos operadores para esto, & , y >> (desplazamiento a la derecha). Así es como podemos extraer los cuatro bytes de un entero de 32 bits:

 void more_stuff(uint32_t value) { // Example value: 0x01020304 uint32_t byte1 = (value >> 24); // 0x01020304 >> 24 is 0x01 so // no masking is necessary uint32_t byte2 = (value >> 16) & 0xff; // 0x01020304 >> 16 is 0x0102 so // we must mask to get 0x02 uint32_t byte3 = (value >> 8) & 0xff; // 0x01020304 >> 8 is 0x010203 so // we must mask to get 0x03 uint32_t byte4 = value & 0xff; // here we only mask, no shifting // is necessary ... } 

Observe que puede cambiar el orden de los operadores de arriba, primero puede hacer la máscara, luego el cambio. Los resultados son los mismos, pero ahora tendrías que usar una máscara diferente:

 uint32_t byte3 = (value & 0xff00) >> 8;