
ПТСПЦУВСБ / 22. Доступ к отдельным битам в С
..docx22. Доступ к отдельным битам в С.
В большинстве случаев процессоры обеспечивают побайтовую адресацию памяти.
Однако, нередки случаи, когда необходимо проанализировать или изменить состояние
отдельных битов. В этих случаях обращаются к ячейке памяти, размер которой кратен
байту, а доступ к отдельным битам обеспечивается с помощью использования побитовых
операторов.
Типичными задачами, требующими работы с отдельными байтами, являются,
например, взаимодействие с периферийными устройствами через их регистры
посредством анализа и изменения состояния битовых флагов и упаковка данных для их
компактного хранения и быстрой передачи по каналам связи.
Для организации полного доступа к отдельным битам числа достаточно обеспечить
выполнение с битом, номер которого задан, трех операций: проверка (англ. check)
состояния бита, установка (англ. set) бита, при которой заданный бит становится равным
1 независимо от исходного состояния и сброс (англ. clear) или маскировка (англ. masking)
бита, при которой заданный бит становится равным 0 независимо от исходного состояния.
Три перечисленные операции могут быть выполнены путем сравнения
анализируемого числа с маской (англ. mask) – целочисленной константой, значение
которой специально подобрано для работы именно с нужным битом.
Например, для установки бита 3 переменной unsigned char a; нужно
выполнить: a=a|00001000b, т.е. a=a|8; или a|=8;, т.к. C не имеет встроенной
поддержки двоичных констант. Для установки бита 7 нужно выполнить:
a=a|10000000b, т.е. a|=128; и т.п.
Таким образом, для независимой от остальных битов установки бита с номером N,
нужно применить операцию побитового “ИЛИ” с маской, двоичное представление
которой содержит 1 только в N-ном бите.
Для независимого от остальных битов сброса (обнуления) бита с номером N, нужно
применить операцию побитового “И” с маской, двоичное представление которой
содержит 0 только в N-ном бите, например, для сброса бита 3 нужно выполнить:
a=a&11110111b, т.е. a&=247;.
Для проверки состояния бита N можно использовать проверку условия с
предварительной маскировкой. Например, для проверки состояния бита 3:
a&=8; //a=a&00001000 – предварительная маскировка
if (a!=0){ //Если бит был установлен
...
}
else{ //Если бит был сброшен
...
}
Задание маски в виде константы неудобно, т.к. для работы с разными битами нужно
каждый раз рассчитывать соответствующие маски. Поэтому на практике маски__
формируют автоматически с помощью операций сдвига. Соответствующие примеры
сведены в таблице 3.15: