Битовое поле
Битовое поле — это структура данных , состоящая из одного или нескольких соседних битов , выделенных для определенных целей, так что любой отдельный бит или группа битов в структуре может быть установлен или проверен. [1] [2] Битовое поле чаще всего используется для представления целочисленных типов известной фиксированной разрядности, таких как однобитовые логические значения .
Значение отдельных битов поля определяется программистом; например, первый бит битового поля (расположенный по базовому адресу поля ) иногда используется для определения состояния определенного атрибута, связанного с битовым полем. [3]
В процессорах и других логических устройствах наборы битовых полей, называемые флагами, обычно используются для управления или указания результата определенных операций. [4] Процессоры имеют регистр состояния , состоящий из флагов. Например, если результат сложения не может быть представлен в месте назначения, арифметическое переполнение устанавливается . Флаги могут использоваться для определения последующих операций, таких как инструкции условного перехода . Например, JE ...
Инструкция (Перейти, если равно) на языке ассемблера x86 приведет к переходу, если флаг Z (ноль) был установлен какой-либо предыдущей операцией.
Битовое поле отличается от битового массива тем, что последний используется для хранения большого набора битов, индексированных целыми числами, и часто шире, чем любой целочисленный тип, поддерживаемый языком. [ нужна ссылка ] С другой стороны, битовые поля обычно помещаются в машинное слово . [3] и обозначение битов не зависит от их числового индекса. [2]
Реализация [ править ]
Битовые поля можно использовать для уменьшения потребления памяти, когда программе требуется несколько целочисленных переменных, которые всегда будут иметь низкие значения. Например, во многих системах для хранения целочисленного значения требуется два байта (16 бит) памяти; иногда для сохранения значений фактически требуется только один или два бита. Наличие нескольких этих крошечных переменных, совместно использующих одно битовое поле, позволяет эффективно упаковывать данные в памяти. [5]
В C битовые поля, определяемые собственной реализацией, могут быть созданы с помощью int
, [а] unsigned int
, signed int
, _Bool
(в C99), _BitInt(N)
, unsigned _BitInt(N)
(в C23) или другие типы, определяемые реализацией. В C++ их можно создавать с использованием любого целочисленного типа или типа перечисления; большинство компиляторов C также допускают это. В этом случае программист может объявить структуру битового поля, которая маркирует и определяет ширину нескольких подполей. [6] Соседне объявленные битовые поля одного и того же типа могут затем быть упакованы компилятором в меньшее количество слов по сравнению с объемом памяти, используемым, если бы каждое «поле» объявлялось отдельно.
Для языков, в которых отсутствуют собственные битовые поля или где программист хочет контролировать результирующее битовое представление, можно вручную манипулировать битами внутри более крупного типа слова. В этом случае программист может устанавливать, проверять и изменять биты в поле, используя комбинации маскирования и побитовых операций . [7]
Примеры [ править ]
Язык программирования C [ править ]
Объявление битового поля в C и C++ : [6]
// opaque and show
#define YES 1
#define NO 0
// line styles
#define SOLID 1
#define DOTTED 2
#define DASHED 3
// primary colors
#define BLUE 0b100
#define GREEN 0b010
#define RED 0b001
// mixed colors
#define BLACK 0 /* 000 */
#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] = {"Black", "Red", "Green", "Yellow", "Blue", "Magenta", "Cyan", "White"};
// bit field box properties
struct BoxProps
{
unsigned int opaque : 1;
unsigned int fill_color : 3;
unsigned int : 4; // fill to 8 bits
unsigned int show_border : 1;
unsigned int border_color : 3;
unsigned int border_style : 2;
unsigned char : 0; // fill to nearest byte (16 bits)
unsigned char width : 4, // Split a byte into 2 fields of 4 bits
height : 4;
};
Расположение битовых полей в C struct
определяется реализацией . Для поведения, которое остается предсказуемым для всех компиляторов, может быть предпочтительнее эмулировать битовые поля с помощью примитивов и битовых операторов:
/* Each of these preprocessor directives defines a single bit,
corresponding to one button on the controller.
Button order matches that of the 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
unsigned char gameControllerStatus = 0;
/* Sets the gameControllerStatus using OR */
void KeyPressed(unsigned char key)
{
gameControllerStatus |= key;
}
/* Clears the gameControllerStatus using AND and ~ (binary NOT)*/
void KeyReleased(unsigned char key)
{
gameControllerStatus &= ~key;
}
/* Tests whether a bit is set using AND */
unsigned char IsPressed(unsigned char key)
{
return gameControllerStatus & key;
}
Эту статью может потребовать очистки Википедии , чтобы она соответствовала стандартам качества . Конкретная проблема: перенесено из поля «Флаг» . ( Май 2016 г. ) |
Регистр состояния процессора [ править ]
Регистр состояния процессора представляет собой битовое поле, состоящее из нескольких битов флагов. Каждый бит флага описывает информацию о текущем состоянии процессора. [8] В качестве примера 6502 ниже показан регистр состояния процессора :
Бит 7 | Бит 6 | Бит 5 | Бит 4 | Бит 3 | Бит 2 | Бит 1 | Бит 0 |
---|---|---|---|---|---|---|---|
Отрицательный флаг | o переполнения Флаг | - | флага Взлом | Десятичный флаг | Я прерываю-отключаю флаг | нуля Флаг нулевого | Нести флаг |
Эти биты устанавливаются процессором по результатам операции. Определенными битами (такими как флаги Carry, Interrupt-disable и Decimal) можно явно управлять с помощью инструкций установки и очистки. Кроме того, определены инструкции ветвления для изменения выполнения в зависимости от текущего состояния флага.
Например, после ADC
(Добавить с переносом), BVS
Инструкция (переход по набору oVerflow) может использоваться для перехода в зависимости от того, был ли флаг переполнения установлен процессором после результата инструкции сложения.
Извлечение битов из слов-флажков [ править ]
Подмножество флагов в поле флага может быть извлечено с помощью операции 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;
Изменение битов в словах-флажках [ править ]
Запись, чтение или переключение битов во флагах можно выполнять только с помощью операций ИЛИ, И и НЕ — операций, которые можно быстро выполнить в процессоре. Чтобы установить бит, ИЛИ байт состояния с байтом маски. Любые биты, установленные в байте маски или байте состояния, будут установлены в результате.
Чтобы немного переключить бит, выполните XOR байт состояния и байт маски. Это установит бит, если он очищен, или немного очистит, если он установлен.
См. также [ править ]
- Двоичный код
- Бит-диапазон
- Битборд , используемый в шахматах и подобных играх.
- Битовый массив (или битовая строка)
- Флаг (программирование)
- Слово (компьютерная архитектура)
- Маска (вычисление)
- Слово состояния программы
- Регистр состояния
- Регистр ФЛАГОВ (вычисления)
- Регистр управления
Примечания [ править ]
- ^ В C зависит от реализации, является ли битовое поле типа int знаковым или беззнаковым. В C++ он всегда имеет подпись, соответствующую базовому типу.
Ссылки [ править ]
- ^ Пенн Брамм; Дон Брамм (август 1988 г.). 80386 Язык ассемблера: полное руководство и библиотека подпрограмм . Группа школьного образования МакГроу-Хилл. п. 606. ИСБН 978-0-8306-9047-3 .
- ↑ Перейти обратно: Перейти обратно: а б Стив Уаллин (1997). Практическое программирование на языке C. «О'Рейли Медиа, Инк.». стр. 403 –. ISBN 978-1-56592-306-5 .
- ↑ Перейти обратно: Перейти обратно: а б Майкл А. Миллер (январь 1992 г.). Семейство микропроцессоров 68000: архитектура, программирование и применение . Меррилл. п. 323. ИСБН 978-0-02-381560-7 .
- ^ Ян Гриффитс; Мэтью Адамс; Джесси Либерти (30 июля 2010 г.). Программирование на C# 4.0: создание приложений Windows, веб-приложений и RIA для .NET 4.0 Framework . «О'Рейли Медиа, Инк.». стр. 81–. ISBN 978-1-4493-9972-6 .
- ^ Тибет Мимар (1991). Программирование и проектирование с использованием семейства 68000: включая 68000, 68010/12, 68020 и 68030 . Прентис Холл. п. 275. ИСБН 978-0-13-731498-0 .
- ↑ Перейти обратно: Перейти обратно: а б Прата, Стивен (2007). C Primer Plus (5-е изд.). Индианаполис, Индиана: Сэмс. ISBN 978-0-672-32696-7 .
- ^ Марк Э. Даггетт (13 ноября 2013 г.). Эксперт по JavaScript . Торопиться. стр. 68–. ISBN 978-1-4302-6097-4 .
- ^ ИнСидер . У. Грин. Январь 1986 г. с. 108.
Внешние ссылки [ править ]
- Объяснение из книги
- Описание из другой вики
- Вариант использования в руководстве по C++
- Битовая библиотека C++ libbit ( альтернативные URL-адреса )
- Bit Twiddling Hacks : несколько фрагментов кода C, манипулирующего битовыми полями