Champ de bits - Bit field

Un champ de bits est une structure de données qui se compose d'un ou plusieurs bits adjacents qui ont été alloués pour contenir une séquence de bits , stockés de sorte que tout bit ou groupe de bits du groupe puisse être défini ou inspecté. Un champ de bits est le plus souvent utilisé pour représenter des types intégraux de largeur de bits fixe connue.

La signification des bits individuels dans le 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 CPU et autres dispositifs logiques, des ensembles de champs de bits appelés « drapeaux » sont couramment utilisés pour contrôler ou indiquer le résultat d'opérations particulières. Les processeurs ont un registre d'état composé d'indicateurs. Par exemple, si le résultat d'une addition ne peut pas être représenté dans la destination, un débordement arithmétique est défini. Les drapeaux peuvent être utilisés pour décider des opérations suivantes, telles que les instructions de saut conditionnel . Par exemple, une instruction (Saut si égal) dans le langage assembleur x86 entraînera un saut si l'indicateur Z (zéro) a été défini par une opération précédente. JE ...

Un champ de bits se distingue d'un tableau de bits en ce que ce dernier est utilisé pour stocker un grand ensemble de bits indexés par des entiers et est souvent plus large que tout type intégral pris en charge par le langage. Les champs de bits, en revanche, tiennent généralement dans un mot machine et la dénotation des bits est indépendante de leur index numérique.

Mise en œuvre

Les champs de bits peuvent être utilisés pour réduire la consommation de mémoire lorsqu'un programme nécessite un certain nombre de variables entières qui auront toujours des valeurs faibles. Par exemple, dans de nombreux systèmes, le stockage d'une valeur entière nécessite deux octets (16 bits) de mémoire ; parfois, les valeurs à stocker n'ont en réalité besoin que d'un ou deux bits. Le fait qu'un certain nombre de ces minuscules variables partagent un champ de bits permet un conditionnement efficace des données dans la mémoire.

En C et C++, les champs de bits natifs définis par l'implémentation peuvent être créés en utilisant un int non signé, un int signé ou (en C99 :) _Bool. 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 déclarés de manière adjacente du même type peuvent alors être compactés par le compilateur en un nombre réduit de mots, par rapport à la mémoire utilisée si chaque "champ" devait être déclaré séparément.

Pour les langues dépourvues de champs binaires natifs, ou lorsque le programmeur souhaite contrôler la représentation binaire résultante, il est possible de manipuler manuellement les bits dans un type de mot plus grand. Dans ce cas, le programmeur peut définir, tester et modifier les bits sur le terrain en utilisant des combinaisons de masquage et d' opérations au niveau des bits .

Exemples

langage de programmation C

Déclarer un champ de bits en C et C++ :

// 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;
};

La disposition des champs de bits dans un C structest définie par l'implémentation . Pour un comportement qui reste prévisible entre les compilateurs, il peut être préférable d'émuler des champs de bits avec une primitive et des opérateurs de bits :

/* 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

int gameControllerStatus = 0;

/* Sets the gameControllerStatus using OR */
void KeyPressed( int key ) { gameControllerStatus |= key; }

/* Clears the gameControllerStatus  using AND and ~ (binary NOT)*/
void KeyReleased( int key ) { gameControllerStatus &= ~key; }

/* Tests whether a bit is set using AND */
int IsPressed( int key ) { return gameControllerStatus & key; }

Registre d'état du processeur

Un exemple de registre d'état des champs de bits est inclus dans le processeur 6502 . Chacun des champs de bits individuels décrit des informations sur l'état de la machine :

  • N indicateur négatif
  • Indicateur de débordement V
  • inutilisé
  • B Drapeau de rupture
  • D Indicateur décimal
  • I Drapeau de désactivation des interruptions
  • Drapeau Z Zéro
  • C Porte drapeau

Ces bits n'ont pas besoin d'être manipulés car ils sont définis par le processeur à la suite d'une opération et sont évalués par des instructions de branchement explicitement définies, par exemple BVC (Branch on overflow Clear), BEQ (Branch Z = 0). L'exception est l'indicateur I pour lequel était une instruction SEI (SEt Interrupt Disable) explicite.

Extraire les bits des mots indicateurs

Un sous-ensemble d'indicateurs dans un champ d'indicateur peut être extrait par AND avec un masque . Un grand nombre de langages prennent en charge l' opérateur de décalage (<<) où 1 << naligne un seul bit sur la nième position et prennent également en charge l'utilisation de l' opérateur AND (&) pour isoler la valeur d'un ou plusieurs bits.

Si l'octet d'état d'un périphérique est 0x67 et que le 5ème bit d'indicateur indique que les données sont prêtes. L'octet de masque est . L'opération AND de l'octet d'état 0x67 ( en binaire) avec l'octet de masque 0x20 ( en binaire) est évaluée à 0x20. Cela signifie que le bit indicateur est défini, c'est-à-dire que l'appareil est prêt pour les données. Si le bit d'indicateur n'avait pas été défini, celui-ci aurait été évalué à 0, c'est-à-dire qu'il n'y a aucune donnée disponible à partir de l'appareil. 0110 01110010 0000

Pour vérifier le n ième bit d'une variable v , effectuez l'opération :

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

Modification des bits dans les mots indicateurs

L'écriture, la lecture ou le basculement des bits dans les drapeaux ne peuvent être effectués qu'à l'aide des opérations OU, ET et NON - opérations qui peuvent être effectuées rapidement dans le processeur. Pour définir un bit, OU l'octet d'état avec un octet de masque. Tous les bits définis dans l'octet de masque ou l'octet d'état seront définis dans le résultat.

Pour basculer un peu, XOR l'octet d'état et l'octet de masque. Cela définira un peu s'il est effacé ou efface un peu s'il est défini.

Voir également

Les références

  1. ^ Penn Brumm; Don Brumm (août 1988). 80386 Assembly Language : Un didacticiel complet et une bibliothèque de sous-programmes . Groupe d'éducation scolaire McGraw-Hill. p. 606. ISBN 978-0-8306-9047-3.
  2. ^ un b Steve Oualline (1997). Programmation C pratique . "O'Reilly Media, Inc.". p.  403 –. ISBN 978-1-56592-306-5.
  3. ^ un b Michael A. Miller (janvier 1992). La famille des microprocesseurs 68000 : architecture, programmation et applications . Merrill. p. 323. ISBN 978-0-02-381560-7.
  4. ^ Ian Griffiths; Matthieu Adams ; Jesse Liberty (30 juillet 2010). Programmation C# 4.0 : création d'applications Windows, Web et RIA pour le framework .NET 4.0 . "O'Reilly Media, Inc.". p. 81–. ISBN 978-1-4493-9972-6.
  5. ^ Tibet Mimar (1991). Programmation et conception avec la famille 68000 : y compris 68000, 68010/12, 68020 et 68030 . Prentice Hall. p. 275. ISBN 978-0-13-731498-0.
  6. ^ un b Prata, Stephen (2007). C primer plus (5e éd.). Indianapolis, Inde : Sams. ISBN 978-0-672-32696-7.
  7. ^ Mark E. Daggett (13 novembre 2013). JavaScript expert . Apress. p. 68–. ISBN 978-1-4302-6097-4.
  8. ^ InCider . W. Vert. janvier 1986. p. 108.

Liens externes