stringtranslate.com

Битовое поле

Битовое поле — это структура данных , состоящая из одного или нескольких соседних битов , выделенных для определенных целей, так что любой отдельный бит или группа битов в структуре может быть установлен или проверен. [1] [2] Битовое поле чаще всего используется для представления целочисленных типов известной фиксированной разрядности, таких как однобитовые логические значения .

Значение отдельных битов поля определяется программистом; например, первый бит битового поля (расположенный по базовому адресу поля ) иногда используется для определения состояния определенного атрибута, связанного с битовым полем. [3]

В процессорах и других логических устройствах наборы битовых полей, называемые флагами, обычно используются для управления или указания результата определенных операций. [4] Процессоры имеют регистр состояния , состоящий из флагов. Например, если результат сложения не может быть представлен в месте назначения, устанавливается арифметическое переполнение . Флаги могут использоваться для определения последующих операций, таких как инструкции условного перехода . Например, инструкция (Перейти, если равно) на языке ассемблера x86 приведет к переходу, если флаг Z (ноль) был установлен какой-либо предыдущей операцией.JE ...

Битовое поле отличается от битового массива тем, что последний используется для хранения большого набора битов, индексированных целыми числами, и часто шире, чем любой целочисленный тип, поддерживаемый языком. [ нужна цитация ] Битовые поля, с другой стороны, обычно вписываются в машинное слово , [3] и обозначение битов не зависит от их числового индекса. [2]

Выполнение

Битовые поля можно использовать для уменьшения потребления памяти, когда программе требуется несколько целочисленных переменных, которые всегда будут иметь низкие значения. Например, во многих системах для хранения целочисленного значения требуется два байта (16 бит) памяти; иногда для сохранения значений фактически требуется только один или два бита. Наличие нескольких этих крошечных переменных, совместно использующих одно битовое поле, позволяет эффективно упаковывать данные в памяти. [5]

В C битовые поля, определяемые собственной реализацией, могут быть созданы с использованием int, [a] unsigned int , signed int, _Bool(в C99), _BitInt(N), unsigned _BitInt(N)(в C23) или других типов, определяемых реализацией. В C++ их можно создавать с использованием любого целочисленного типа или типа перечисления; большинство компиляторов C также допускают это. В этом случае программист может объявить структуру битового поля, которая маркирует и определяет ширину нескольких подполей. [6] Смежно объявленные битовые поля одного и того же типа могут затем быть упакованы компилятором в меньшее количество слов по сравнению с объемом памяти, используемым, если бы каждое «поле» объявлялось отдельно.

Для языков, в которых отсутствуют собственные битовые поля или где программист хочет контролировать результирующее битовое представление, можно вручную манипулировать битами внутри более крупного типа слова. В этом случае программист может устанавливать, проверять и изменять биты в поле, используя комбинации маскирования и побитовых операций . [7]

Примеры

язык программирования Си

Объявление битового поля в C и C++ : [6]

// непрозрачность и отображение #define YES 1 #define NO 0// стили линий #define SOLID 1 #define DOTTED 2 #define DASHED 3// основные цвета #define BLUE 0b100 #define GREEN 0b010 #define RED 0b001// смешанные цвета #define BLACK 0 /* 000 */ #define YELLOW (RED | GREEN) /* 011 */ #define MAGENTA (RED | BLUE) /* 101 */ #define CYAN (GREEN | BLUE) /* 110 */ #define БЕЛЫЙ (КРАСНЫЙ | ЗЕЛЕНЫЙ | СИНИЙ) /* 111 */const char * Colors [ 8 ] = { «Черный» , «Красный» , «Зеленый» , «Желтый» , «Синий» , «Пурпурный» , «Голубой» , «Белый» };           // свойства блока битового поля struct BoxProps { unsigned int opaque : 1 ; беззнаковый int fill_color : 3 ; беззнаковое целое : 4 ; // заполняем до 8 бит unsigned int show_border : 1 ; беззнаковый int border_color : 3 ; беззнаковый int border_style : 2 ; беззнаковый символ : 0 ; // заполняем до ближайшего байта (16 бит) unsigned char width : 4 , // разделяем байт на 2 поля по 4 бита высотой : 4 ; };                                             


Расположение битовых полей в C structопределяется реализацией . Для поведения, которое остается предсказуемым для всех компиляторов, может быть предпочтительнее эмулировать битовые поля с помощью примитивов и битовых операторов:

/* Каждая из этих директив препроцессора определяет один бит,  соответствующий одной кнопке контроллера.  Порядок кнопок соответствует порядку кнопок Nintendo Entertainment System. */ #define KEY_RIGHT 0b00000001 #define KEY_LEFT 0b00000010 #define KEY_DOWN 0b00000100 #define KEY_UP 0b00001000 #define KEY_START 0b00010000 #define KEY_SELECT 0b00100000 #define KEY_B 0b 01000000 #define KEY_A 0b10000000беззнаковый символ gameControllerStatus = 0 ;    /* Устанавливает gameControllerStatus с помощью OR */ void KeyPressed ( беззнаковый символьный ключ ) { gameControllerStatus |= key ; }         /* Очищает gameControllerStatus с помощью AND и ~ (двоичное NOT)*/ void KeyReleased ( беззнаковый символьный ключ ) { gameControllerStatus &= ~ key ; }         /* Проверяет, установлен ли бит с помощью AND */ unsigned char IsPressed ( unsigned char key ) { return gameControllerStatus & key ; }           

Регистр состояния процессора

Регистр состояния процессора представляет собой битовое поле, состоящее из нескольких битов флагов. Каждый бит флага описывает информацию о текущем состоянии процессора. [8] В качестве примера ниже показан регистр состояния процессора 6502 :

Эти биты устанавливаются процессором по результатам операции. Определенными битами (такими как флаги Carry, Interrupt-disable и Decimal) можно явно управлять с помощью инструкций установки и очистки. Кроме того, определены инструкции ветвления для изменения выполнения в зависимости от текущего состояния флага.

Например, после ADCинструкции (Добавить с переносом) BVSинструкция (Переход при наборе oVerflow) может использоваться для перехода в зависимости от того, был ли флаг переполнения установлен процессором после результата инструкции сложения.

Извлечение битов из слов-флажков

Подмножество флагов в поле флага может быть извлечено с помощью операции AND с маской . Большое количество языков поддерживают оператор сдвига (<<), где 1 << nодин бит выравнивается по n-й позиции. Большинство из них также поддерживают использование оператора AND (&) для изоляции значения одного или нескольких битов.

Если байт состояния устройства равен 0x67, а 5-й бит флага указывает на готовность данных. Байт-маска равен 2^5 = 0x20. Соединение байта состояния 0x67 ( 0110 0111в двоичном формате) с байтом маски 0x20 ( 0010 0000в двоичном формате) дает значение 0x20. Это означает, что бит флага установлен, т. е. устройство готово к передаче данных. Если бы бит флага не был установлен, он был бы равен 0, т. е. от устройства нет доступных данных.

Чтобы проверить n -й бит переменной v , выполните одно из следующих действий: (оба эквивалентны)

bool nth_is_set = ( v & (1 << n )) != 0;bool nth_is_set = ( v >> n ) & 1;

Изменение битов в словах-флагах

Запись, чтение или переключение битов во флагах можно выполнять только с помощью операций ИЛИ, И и НЕ — операций, которые можно быстро выполнить в процессоре. Чтобы установить бит, ИЛИ байт состояния с байтом маски. Любые биты, установленные в байте маски или байте состояния, будут установлены в результате.

Чтобы немного переключить бит, выполните XOR байт состояния и байт маски. Это установит бит, если он очищен, или немного очистит, если он установлен.

Смотрите также

Примечания

  1. ^ В C зависит от реализации, является ли битовое поле типа int знаковым или беззнаковым. В C++ он всегда имеет подпись, соответствующую базовому типу.

Рекомендации

  1. ^ Пенн Брамм; Дон Брамм (август 1988 г.). 80386 Язык ассемблера: полное руководство и библиотека подпрограмм. Группа школьного образования МакГроу-Хилл. п. 606. ИСБН 978-0-8306-9047-3.
  2. ^ ab Стив Уаллин (1997). Практическое программирование на языке C. «О'Рейли Медиа, Инк.». стр. 403–. ISBN 978-1-56592-306-5.
  3. ^ AB Майкл А. Миллер (январь 1992 г.). Семейство микропроцессоров 68000: архитектура, программирование и применение. Меррилл. п. 323. ИСБН 978-0-02-381560-7.
  4. ^ Ян Гриффитс; Мэтью Адамс; Джесси Либерти (30 июля 2010 г.). Программирование на C# 4.0: создание приложений Windows, веб-приложений и RIA для .NET 4.0 Framework. «О'Рейли Медиа, Инк.». стр. 81–. ISBN 978-1-4493-9972-6.
  5. ^ Тибет Мимар (1991). Программирование и проектирование с использованием семейства 68000: включая 68000, 68010/12, 68020 и 68030. Prentice Hall. п. 275. ИСБН 978-0-13-731498-0.
  6. ^ Аб Прата, Стивен (2007). C Primer Plus (5-е изд.). Индианаполис, Индиана: Сэмс. ISBN 978-0-672-32696-7.
  7. ^ Марк Э. Даггетт (13 ноября 2013 г.). Экспертный JavaScript. Апресс. стр. 68–. ISBN 978-1-4302-6097-4.
  8. ^ ИнСидер. У. Грин. Январь 1986 г. с. 108.

Внешние ссылки