stringtranslate.com

Битовое поле

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

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

В процессорах и других логических устройствах наборы битовых полей, называемых флагами, обычно используются для управления или указания результата определенных операций. [4] Процессоры имеют регистр состояния , состоящий из флагов. Например, если результат сложения не может быть представлен в месте назначения, устанавливается арифметическое переполнение . Флаги могут использоваться для определения последующих операций, таких как инструкции условного перехода . Например, инструкция (Jump if Equal) на языке ассемблера 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 СИНИЙ 0b100 #define ЗЕЛЕНЫЙ 0b010 #define КРАСНЫЙ 0b001// смешанные цвета #define BLACK 0 #define YELLOW (RED | GREEN) /* 011 */ #define MAGENTA (RED | BLUE) /* 101 */ #define CYAN (GREEN | BLUE) /* 110 */ #define WHITE (RED | GREEN | BLUE) /* 111 */const char * colors [ 8 ] = { "Черный" , "Красный" , "Зеленый" , "Желтый" , "Синий" , "Пурпурный" , "Голубой" , "Белый" };           // свойства поля битового поля struct BoxProps { unsigned int opaque : 1 ; unsigned int fill_color : 3 ; unsigned int : 4 ; // заполнить до 8 бит unsigned int show_border : 1 ; unsigned int border_color : 3 ; unsigned int border_style : 2 ; unsigned char : 0 ; // заполнить до ближайшего байта (16 бит) unsigned char width : 4 , // Разбить байт на 2 поля по 4 бита height : 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 0b01000000 #define KEY_A 0b10000000беззнаковый символ gameControllerStatus = 0 ;    /* Устанавливает gameControllerStatus с помощью OR */ void KeyPressed ( unsigned char key ) { gameControllerStatus |= key ; }         /* Очищает gameControllerStatus с помощью AND и ~ (двоичное NOT)*/ void KeyReleased ( unsigned char key ) { gameControllerStatus &= ~ key ; }         /* Проверяет, установлен ли бит, с помощью AND */ unsigned char IsPressed ( unsigned char key ) { return gameControllerStatus & key ; }           

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

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

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

Например, после ADCинструкции (Add with Carry) BVSможно использовать инструкцию (Branch on oVerflow Set) для перехода в зависимости от того, был ли установлен процессором флаг переполнения после результата инструкции сложения.

Извлечение битов из флаговых слов

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

Если байт состояния устройства равен 0x67, а 5-й бит флага указывает на готовность данных. Байт маски равен 2^5 = 0x20. Операция AND байта состояния 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;

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

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

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

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

Примечания

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

Ссылки

  1. ^ Пенн Брамм; Дон Брамм (август 1988). 80386 Язык ассемблера: Полное учебное пособие и библиотека подпрограмм. McGraw-Hill School Education Group. стр. 606. ISBN 978-0-8306-9047-3.
  2. ^ ab Стив Уаллин (1997). Практическое программирование на языке C. "O'Reilly Media, Inc.". стр. 403–. ISBN 978-1-56592-306-5.
  3. ^ ab Майкл А. Миллер (январь 1992 г.). Семейство микропроцессоров 68000: архитектура, программирование и приложения. Merrill. стр. 323. ISBN 978-0-02-381560-7.
  4. ^ Ян Гриффитс; Мэтью Адамс; Джесси Либерти (30 июля 2010 г.). Программирование на C# 4.0: Создание приложений Windows, Web и RIA для .NET 4.0 Framework. "O'Reilly Media, Inc.". С. 81–. ISBN 978-1-4493-9972-6.
  5. ^ Тибет Мимар (1991). Программирование и проектирование с семейством 68000: включая 68000, 68010/12, 68020 и 68030. Prentice Hall. стр. 275. ISBN 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. InCider. W. Green. Январь 1986. С. 108.

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