Bitfelt - Bit field

Et bitfelt er en datastruktur, der består af en eller flere tilstødende bits, som er blevet tildelt til at indeholde en række bits , der er lagret, så enhver enkelt bit eller gruppe af bits i gruppen kan indstilles eller inspiceres. Et bitfelt bruges mest til at repræsentere integrale typer af kendt, fast bitbredde.

Betydningen af ​​de enkelte bits inden for feltet bestemmes af programmøren; for eksempel bruges den første bit i et bitfelt (placeret ved feltets basisadresse ) undertiden til at bestemme tilstanden for en bestemt attribut, der er knyttet til bitfeltet.

Inden for CPU'er og andre logiske enheder bruges samlinger af bitfelter kaldet "flag" almindeligvis til at styre eller angive resultatet af bestemte operationer. Processorer har et statusregister , der består af flag. Hvis for eksempel resultatet af en tilføjelse ikke kan repræsenteres i destinationen, indstilles et aritmetisk overløb . Flagene kan bruges til at bestemme efterfølgende operationer, f.eks. Betingede springinstruktioner . For eksempel vil en (Jump if Equal) instruktion i x86 -samlingsproget resultere i et spring, hvis Z (nul) -flaget blev indstillet af en tidligere operation. JE ...

Et bitfelt adskiller sig fra et bitarray ved, at sidstnævnte bruges til at gemme et stort sæt bits indekseret af heltal og ofte er bredere end nogen integraltype, der understøttes af sproget. Bit felter, på den anden side, passer typisk inden for en maskine ord , og denotation af bits er uafhængig af deres numeriske indeks.

Implementering

Bitfelter kan bruges til at reducere hukommelsesforbruget, når et program kræver et antal heltalsvariabler, der altid vil have lave værdier. For eksempel kræver mange systemer lagring af en heltalsværdi to bytes (16-bit) hukommelse; nogle gange behøver de værdier, der skal lagres, faktisk kun en eller to bits. At have et antal af disse små variabler deler et bitfelt tillader effektiv pakning af data i hukommelsen.

I C og C ++ kan native implementeringsdefinerede bitfelter oprettes ved hjælp af usigneret int, signeret int eller (i C99 :) _Bool. I dette tilfælde kan programmereren erklære en struktur for et bitfelt, der mærker og bestemmer bredden af ​​flere underfelter. Tilstødende deklarerede bitfelter af samme type kan derefter pakkes af kompilatoren i et reduceret antal ord sammenlignet med den anvendte hukommelse, hvis hvert 'felt' skulle deklareres separat.

For sprog, der mangler native bitfields, eller hvor programmøren ønsker kontrol over den resulterende bitrepræsentation, er det muligt manuelt at manipulere bits inden for en større ordtype. I dette tilfælde kan programmereren indstille, teste og ændre bitene i feltet ved hjælp af kombinationer af maskering og bitvise operationer .

Eksempler

C programmeringssprog

Angivelse af et bitfelt i C og 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;
};

Layoutet af bitfelter i en C structer implementeringsdefineret . For adfærd, der forbliver forudsigelig på tværs af kompilatorer, kan det være at foretrække at efterligne bitfelter med en primitiv og bitoperatorer:

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

Processorstatusregister

Et eksempel på bitfields statusregister er inkluderet i 6502 -processoren. Hver af de enkelte bitfelter beskriver oplysninger om maskintilstanden:

  • N Negativt flag
  • V oVerflow flag
  • ubrugt
  • B Knæk flag
  • D Decimalflag
  • I Afbryd-deaktiver flag
  • Z Nul flag
  • C Bær flag

Disse bits behøver ikke at manipuleres, da de er indstillet af processoren som et resultat af en operation og evalueres ved eksplicit definerede forgreningsinstruktioner for eksempel BVC (Branch on oVerflow Clear), BEQ (Gren Z = 0). Undtagelsen er det I -flag, som var en eksplicit SEI (SEt Interrupt Disable) instruktion.

Udtræk af bits fra flagord

Et undersæt af flag i et flagfelt kan ekstraheres ved at ANDe med en maske . Et stort antal sprog understøtter skiftoperatoren (<<), hvor 1 << nen enkelt bit justeres til den niende position understøtter også brugen af AND -operatoren (&) til at isolere værdien af ​​en eller flere bits.

Hvis status-byte fra en enhed er 0x67, og 5. flagbit angiver dataklar. Maskebyten er . OGing af status-byte 0x67 ( i binær) med maske-byte 0x20 ( i binær) evalueres til 0x20. Det betyder, at flagbitten er indstillet, dvs. enheden har dataklar. Hvis flag-bit ikke var blevet indstillet, ville dette have været evalueret til 0 dvs. der er ingen data tilgængelige fra enheden. 0110 01110010 0000

For at kontrollere den n. Bit fra en variabel v , udfør operationen:

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

Ændring af bits i flagord

At skrive, læse eller skifte bits i flag kan kun udføres ved hjælp af OR, AND og NOT operationerne - operationer, der kan udføres hurtigt i processoren. For at indstille lidt, ELLER statusbyten med en maskebyte. Eventuelle bits, der er angivet i maskebyten eller statusbyten, indstilles i resultatet.

For at skifte lidt, XOR statusbyte og maskebyte. Dette vil sætte en smule, hvis det er ryddet eller rydde lidt, hvis det er indstillet.

Se også

Referencer

  1. ^ Penn Brumm; Don Brumm (august 1988). 80386 Monteringssprog: Et komplet selvstudie- og underprogrambibliotek . McGraw-Hill School Education Group. s. s. 606. ISBN 978-0-8306-9047-3.
  2. ^ a b Steve Oualline (1997). Praktisk C -programmering . "O'Reilly Media, Inc.". s.  403 -. ISBN 978-1-56592-306-5.
  3. ^ a b Michael A. Miller (januar 1992). 68000 mikroprocessorfamilien: Arkitektur, programmering og applikationer . Merrill. s. s. 323. ISBN 978-0-02-381560-7.
  4. ^ Ian Griffiths; Matthew Adams; Jesse Liberty (30. juli 2010). Programmering af C# 4.0: Bygning af Windows-, web- og RIA -applikationer til .NET 4.0 Framework . "O'Reilly Media, Inc.". s. 81–. ISBN 978-1-4493-9972-6.
  5. ^ Tibet Mimar (1991). Programmering og design med 68000 -familien: Inkluderet 68000, 68010/12, 68020 og 68030 . Prentice Hall. s. s. 275. ISBN 978-0-13-731498-0.
  6. ^ a b Prata, Stephen (2007). C primer plus (5. udgave). Indianapolis, Ind: Sams. ISBN 978-0-672-32696-7.
  7. ^ Mark E. Daggett (13. november 2013). Ekspert JavaScript . Undgå. s. 68–. ISBN 978-1-4302-6097-4.
  8. ^ InCider . W. Grøn. Januar 1986. s. 108.

eksterne links