Ответ 1
Маска определяет, какие биты вы хотите сохранить, и какие биты вы хотите очистить.
Маскировка - это действие применения маски к значению. Это достигается тем, что:
- Побитовое ANDing для извлечения подмножества бит в значении
- Побитовое ORing для установки подмножества бит в значении
- Побитовое XORing для переключения подмножества бит в значение
Ниже приведен пример извлечения подмножества бит в значении:
Mask: 00001111b
Value: 01010101b
Применение маски к значению означает, что мы хотим очистить первые (более высокие) 4 бита и сохранить последние (более низкие) 4 бита. Таким образом, мы извлекли более низкие 4 бита. Результат:
Mask: 00001111b
Value: 01010101b
Result: 00000101b
Маскировка выполняется с использованием AND, поэтому в C мы получаем:
uint8_t stuff(...) {
uint8_t mask = 0x0f; // 00001111b
uint8_t value = 0x55; // 01010101b
return mask & value;
}
Вот довольно распространенный прецедент: извлечение отдельных байтов из большего слова. Мы определяем старшие биты в слове как первый байт. Для этого мы используем два оператора: &
и >>
(сдвиг вправо). Так мы можем извлечь четыре байта из 32-разрядного целого числа:
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
...
}
Обратите внимание, что вы можете переключить порядок операторов выше, вы можете сначала сделать маску, затем сдвиг. Результаты те же, но теперь вам придется использовать другую маску:
uint32_t byte3 = (value & 0xff00) >> 8;