Bitmező

A bitmező egy olyan adatszerkezet, amely egy vagy több szomszédos bitet képez le, amelyek meghatározott célokra lettek lefoglalva, így a struktúrán belül bármelyik bit vagy bitcsoport beállítható vagy ellenőrizhető.[1][2] A bitmezőt leggyakrabban ismert, rögzített bitszélességű elemi típusok, például az egybites logikai típus ábrázolására használják.

A mezőn belül az egyes bitek jelentését a programozó határozza meg; például a bitmező első bitjét (amely a mező alapcímén[3] található) néha arra használják, hogy meghatározzák a bitmezőhöz tartozó adott attribútum állapotát.[4]

A CPU-kban és más logikai eszközökben a flag-eknek[5] nevezett bitmezők csoportjait általában arra használják, hogy bizonyos műveletek eredményét ellenőrizzék vagy jelezzék.[6] A processzorok rendelkeznek egy állapotregiszterrel, amely flag-ekből áll.[7] Például, ha egy összeadás eredménye nem ábrázolható a célban, akkor aritmetikai túlcsordulást jelez.[8] A flag-ek (jelzők) felhasználhatók a későbbi műveletek, például a feltételes ugróutasítások eldöntésére.[9] Például egy JE ... („Jump if Equal” – Ugrás, ha egyenlő) utasítás az x86 assembly nyelvben ugráshoz vezet, ha a Z (zéró) flag-et valamilyen korábbi művelet beállította (ha a Z-flag értéke 1 lett).

A bitmezőt az különbözteti meg a bittömböktől, hogy az utóbbi egész számokkal indexelt bitek nagy halmazának tárolására szolgál, és gyakran szélesebb, mint a nyelv által támogatott bármely egész típus. A bitmezők ezzel szemben jellemzően egy gépi szóba illeszkednek,[4] és a bitek jelölése független a numerikus indexüktől.[2]

Megvalósítás

A bitmezők felhasználhatók a memóriafogyasztás csökkentésére, ha egy programnak számos olyan egészértékű változóra van szüksége, amelyeknek mindig alacsony értékei lesznek. Például sok rendszerben egy egész számérték tárolásához két bájt (16 bit) memóriára van szükség; néha a tárolandó értékek valójában csak egy vagy két bitet igényelnek. Ha több ilyen apró változó osztozik egy bitmezőn, az lehetővé teszi az adatok hatékony tömörítését a memóriában.[10]

C-ben a natív implementáció által meghatározott bitmezők létrehozhatók az int,[11] unsigned int, signed int, _Bool (C99-ben(wd)), _BitInt(N), unsigned _BitInt(N) (C23-ban(wd)) vagy más implementáció által meghatározott típusokkal. C++-ban bármilyen egész vagy felsorolás típus használatával létrehozhatók; a legtöbb C fordító ezt is lehetővé teszi. Ebben az esetben a programozó deklarálhat egy bitmező-struktúrát, amely több almezőt címkéz és meghatározza a szélességét.[12] Az azonos típusú, egymás mellett deklarált bitmezőket a fordító kevesebb szóba pakolhatja, mintha minden egyes „mezőt” külön-külön kellene deklarálni.

Azon nyelvek esetében, amelyek nem rendelkeznek natív bitmezőkkel, vagy ahol a programozónak szüksége van a bitek megjelenítésének ellenőrzésére, lehetőség van a bitek kézi manipulálására egy hosszabb szótípuson belül. Ebben az esetben a programozó maszkolás(wd) és bitenkénti műveletek kombinációival állíthatja be, tesztelheti és módosíthatja a mező bitjeit.[13]

Példák

C programozási nyelv

Bitmező deklarálása C és C++ nyelven:[12]

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

A C struktúrák (struct) bitmezőinek elrendezése a megvalósítás függvénye.[14] Ha a viselkedés kiszámítható marad a különböző fordítóprogramok között, akkor előnyösebb lehet a bitmezőket elemi és bitműveletekkel emulálni:

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

Processzor állapotregiszter

A processzor állapotregisztere egy több jelzőbitből (flag) álló bitmező. Minden egyes flag bit a processzor aktuális állapotára vonatkozó információt ír le.[15] Példaként a 6502 processzor állapotregisztere(wd) az alábbiakban látható:

A 6502-es processzor állapotregiszter bitjei
Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0
Negative flag oVerflow flag - Break flag Decimal flag Interrupt-disable flag Zero flag Carry flag

Ezeket a biteket a processzor a művelet eredményét követően állítja be. Bizonyos bitek (például a carry(wd) (átvitelbit), az interrupt-disable, és a decimal flag) kifejezetten vezérelhetők, egyedi set és clear utasításokkal beállíthatók vagy törölhetők. Ezen kívül minden architektúrában feltételes elágazási utasítások(wd) is (pl. JNZ (x86), BEQ, BNE, BCS, BCC, stb. (PDP-11, 6502, ARM) definiálva vannak, hogy a végrehajtás sorrendjét a flag aktuális állapota szerint megváltoztassák.

Például egy ADC (Add with Carry) utasítás után a BVS (Branch on oVerflow Set) utasítás használható az ugráshoz annak alapján, hogy a processzor az összeadási utasítás eredményét követően a túlcsordulási jelzőt beállította-e.

Bitek kivonása a flag-szavakból

A flag-mezőben lévő flagek egy részhalmaza kivonható egy AND maszkolással(wd). Számos nyelv támogatja a shift operátort (<<), ahol az 1 << n egy bitet az n-edik pozícióba igazít. A legtöbb nyelv támogatja az AND operátor (&) használatát is egy vagy több bit értékének elkülönítésére.

Ha egy eszköz állapotbájtja 0x67, és az 5. flag bit adat-készenlét állapotot jelez. A maszk-byte 2^5 = 0x20. A 0x67 állapot-byte (0110 0111 binárisan) és a 0x20 maszk-byte (0010 0000 binárisan) AND-művelete 0x20-at eredményez. Ez azt jelenti, hogy a jelzőbit be van állítva, azaz az eszköz készen áll az adatokra. Ha a flag-bit nem lett volna beállítva, akkor ez 0-ra értékelődne ki, azaz az eszközről nem áll rendelkezésre adat.

A v változó n-edik bitjének ellenőrzéséhez hajtsa végre a következők valamelyikét: (mindkettő egyenértékű)

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

A bitek megváltoztatása a flag-szavakban

A flag-word bitjeinek írása, olvasása vagy átváltása csak a OR, AND és NOT műveletekkel végezhető el – ezek a műveletek gyorsan elvégezhetők a processzorban. Egy bit beállításához az állapotbájtot és egy maszkbájtot kell „VAGY-olni”. A maszkbájtban vagy az állapotbájtban beállított bitek az eredményben is be lesznek állítva.

Egy bit váltásához „XOR-olni” kell az állapotbájtot és a maszkbájtot. Ez egy bitet be fog állítani, ha törölve van, vagy törölni fog egy bitet, ha be van állítva, így ellentettjére állítva azokat.

Lásd még

Jegyzetek

  1. 80386 Assembly Language: A Complete Tutorial and Subroutine Library. McGraw-Hill School Education Group, 606. o. (1988. augusztus 1.). ISBN 978-0-8306-9047-3 
  2. a b Steve Oualline. Practical C Programming. "O'Reilly Media, Inc.", 403–. o. (1997). ISBN 978-1-56592-306-5 
  3. A számítástechnikában az alapcím (base address) egy olyan cím(wd), amely más címek számára referenciapontként („bázisként”) szolgál.
  4. a b Michael A. Miller. The 68000 Microprocessor Family: Architecture, Programming, and Applications. Merrill, 323. o. (1992. január 1.). ISBN 978-0-02-381560-7 
  5. A számítógépes programozásban a flag (jelző) egy vagy több bitre utalhat, amelyek egy bináris érték vagy egy logikai változó tárolására szolgálnak speciális kódfeltételek jelzésére.
  6. Programming C# 4.0: Building Windows, Web, and RIA Applications for the .NET 4.0 Framework. "O'Reilly Media, Inc.", 81–. o. (2010. július 30.). ISBN 978-1-4493-9972-6 
  7. Az állapotregiszter(wd), státuszregiszter, flag-regiszter vagy állapotkódregiszter (condition code register, CCR) a processzor állapotjelző bitjeinek gyűjteménye.
  8. A számítógépes programozásban az egész számok túlcsordulása (integer overflow) akkor fordul elő, amikor egy aritmetikai művelet olyan számértéket próbál létrehozni, amely kívül esik az adott számjegyszámmal ábrázolható tartományon – vagy nagyobb, mint a maximális, vagy kisebb, mint a minimális ábrázolható érték.
  9. Az elágazás (branch), ugrás (jump) vagy átvitel (transfer) olyan utasítás a számítógépes programban, amely a számítógépet egy másik utasítássorozat végrehajtásának(wd) megkezdésére késztetheti, és így eltérhet az alapértelmezett viselkedéstől, azaz az utasítások sorrendben történő végrehajtásától.
  10. Tibet Mimar. Programming and Designing with the 68000 Family: Including 68000, 68010/12, 68020, and the 68030. Prentice Hall, 275. o. (1991). ISBN 978-0-13-731498-0 
  11. A C nyelvben az implementáció határozza meg, hogy egy int típusú bitmező előjeles vagy előjel nélküli. A C++-ban mindig előjeles, hogy megfeleljen a mögöttes típusnak.
  12. a b Prata, Stephen. C primer plus, 5th, Indianapolis, Ind: Sams (2007). ISBN 978-0-672-32696-7 
  13. Mark E. Daggett. Expert JavaScript. Apress, 68–. o. (2013. november 13.). ISBN 978-1-4302-6097-4 
  14. A számítógép-programozásban a nem specifikált viselkedés (unspecified behavior) olyan tulajdonság, amely egy programozási nyelv különböző implementációinál eltérő lehet.
  15. InCider. W. Green, 108. o. (1986. január 1.) 

Fordítás

  • Ez a szócikk részben vagy egészben a Bit field című angol Wikipédia-szócikk fordításán alapul. Az eredeti cikk szerkesztőit annak laptörténete sorolja fel. Ez a jelzés csupán a megfogalmazás eredetét és a szerzői jogokat jelzi, nem szolgál a cikkben szereplő információk forrásmegjelöléseként.

 

Prefix: a b c d e f g h i j k l m n o p q r s t u v w x y z 0 1 2 3 4 5 6 7 8 9

Portal di Ensiklopedia Dunia