Bitmező

adatszerkezet From Wikipedia, the free encyclopedia

Remove ads

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]

Remove ads

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]

Remove ads

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ó:

További információk Bit 7, Bit 6 ...

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.

Remove ads

Lásd még

Jegyzetek

Fordítás

Loading related searches...

Wikiwand - on

Seamless Wikipedia browsing. On steroids.

Remove ads