Un champ de bits est une structure de données qui associe un ou plusieurs bits adjacents alloués à des fins spécifiques, de sorte que n'importe quel bit ou groupe de bits au sein de la structure puisse être défini ou examiné. Un champ de bits est le plus souvent utilisé pour représenter des types entiers de largeur de bits connue et fixe, tels que les booléens à un seul bit .
La signification des bits individuels au sein du champ est déterminée par le programmeur ; par exemple, le premier bit d’un champ de bits (situé à l’ adresse de base du champ ) est parfois utilisé pour déterminer l’état d’un attribut particulier associé au champ de bits.
Dans les processeurs et autres dispositifs logiques, des ensembles de champs binaires appelés drapeaux sont couramment utilisés pour contrôler ou indiquer le résultat d'opérations particulières. Les processeurs possèdent un registre d'état composé de drapeaux. Par exemple, si le résultat d'une addition ne peut être représenté dans la destination, un dépassement de capacité arithmétique est déclenché. Les drapeaux peuvent servir à déterminer les opérations suivantes, telles que les instructions de saut conditionnel . Par exemple, une instruction « Jump if Equal » (Saut si égal) en langage assembleur x86 effectuera un saut si le drapeau Z (zéro) a été activé par une opération précédente.JE...
Un champ de bits se distingue d'un tableau de bits par le fait que ce dernier sert à stocker un grand ensemble de bits indexés par des entiers et est souvent plus large que n'importe quel type entier pris en charge par le langage. Les champs de bits, quant à eux, tiennent généralement dans un mot machine [ et la désignation des bits est indépendante de leur index numérique
Mise en œuvre
Les champs de bits permettent de réduire la consommation de mémoire lorsqu'un programme nécessite plusieurs variables entières qui auront toujours des valeurs faibles. Par exemple, dans de nombreux systèmes, le stockage d'une valeur entière requiert deux octets (16 bits) de mémoire ; or, certaines valeurs à stocker ne nécessitent qu'un ou deux bits. Le fait de regrouper plusieurs de ces petites variables dans un champ de bits permet un stockage efficace des données en mémoire.
En C, les champs de bits natifs définis par l'implémentation peuvent être créés à l'aide de int , ` int` (en C99 ), ` int` (en C23 ) ou d'autres types définis par l'implémentation. En C++, ils peuvent être créés à l'aide de n'importe quel type entier ou énuméré ; la plupart des compilateurs C le permettent également. Dans ce cas, le programmeur peut déclarer une structure pour un champ de bits qui étiquette et détermine la largeur de plusieurs sous-champs. Les champs de bits adjacents du même type peuvent alors être regroupés par le compilateur dans un nombre réduit de mots, comparé à la mémoire utilisée si chaque « champ » était déclaré séparément.unsigned intsigned int_Bool_BitInt(N)unsigned _BitInt(N)
Pour les langages dépourvus de champs de bits natifs, ou lorsque le programmeur souhaite contrôler la représentation binaire résultante, il est possible de manipuler manuellement les bits au sein d'un type de mot plus large. Dans ce cas, le programmeur peut définir, tester et modifier les bits du champ en utilisant des combinaisons de masquage et d'opérations bit à bit .
Exemples
C
Les champs de bits peuvent être utilisés à l'intérieur des structures en C et C++ .
La disposition des champs de bits en C structest définie par l'implémentation . Pour un comportement prévisible d'un compilateur à l'autre, il peut être préférable d'émuler les champs de bits avec un type primitif et des opérateurs binaires :
Rouiller
Bien que Rust ne dispose pas de champs de bits natifs de type C, cela est réalisé à l'aide de masques.
Registre d'état du processeur
Le registre d'état d'un processeur est un champ de bits composé de plusieurs bits d'indicateur. Chaque bit d'indicateur décrit des informations sur l'état actuel du processeur. À titre d'exemple, le registre d'état du processeur 6502 est présenté ci-dessous :
Ces bits sont positionnés par le processeur à la suite du résultat d'une opération. Certains bits (comme les indicateurs de retenue, de désactivation d'interruption et de décimal) peuvent être contrôlés explicitement à l'aide des instructions de mise à 1 et de mise à 0. De plus, des instructions de branchement permettent de modifier l'exécution en fonction de l'état actuel d'un indicateur.
Par exemple, après une ADCinstruction (Add with Carry), l' BVSinstruction (Branch on oVerflow Set) peut être utilisée pour effectuer un saut en fonction du fait que l' indicateur de dépassement a été défini par le processeur à la suite du résultat de l'instruction d'addition.
Extraction de bits à partir de mots-clés.
Dans un champ de drapeaux, on peut extraire un sous-ensemble de valeurs en effectuant un ET logique avec un masque . De nombreux langages prennent en charge l' opérateur de décalage ( < < ) qui 1 << naligne un bit à la position n. La plupart prennent également en charge l' opérateur ET logique (&) pour isoler la valeur d'un ou plusieurs bits.
Si l'octet d'état d'un périphérique est 0x67 et que le 5e bit d'indicateur signale la disponibilité des données, alors l'octet de masque est 0x20 2^5 = 0x20. Un ET logique entre l'octet d'état 0x67 ( en binaire) et l'octet de masque 0x20 ( en binaire) donne 0x20. Cela signifie que le bit d'indicateur est activé, c'est-à-dire que le périphérique a des données disponibles. Si le bit d'indicateur n'avait pas été activé, le résultat aurait été 0, indiquant qu'aucune donnée n'est disponible.0110011100100000
Pour vérifier le n -ième bit d'une variable v , effectuez l'une des opérations suivantes : (les deux sont équivalentes)
Modification de certains éléments dans les mots de drapeau
L'écriture, la lecture ou la modification des bits dans les drapeaux ne peuvent être effectuées qu'à l'aide des opérations OU, ET et NON, opérations rapides pour le processeur. Pour activer un bit, effectuez un OU logique entre l'octet d'état et un octet de masque. Tout bit activé dans l'octet de masque ou l'octet d'état sera activé dans le résultat.
Pour inverser l'état d'un bit, effectuez un XOR entre l'octet d'état et l'octet de masque. Cela activera le bit s'il est à zéro, ou le désactivera s'il est à un.