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ő. 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énA számítástechnikában az alapcím (base address) egy olyan cím, amely más címek számára referenciapontként („bázisként”) szolgál. található) néha arra használják, hogy meghatározzák a bitmezőhöz tartozó adott attribútum állapotát.

A CPU-kban és más logikai eszközökben a flag-eknekA 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. nevezett bitmezők csoportjait általában arra használják, hogy bizonyos műveletek eredményét ellenőrizzék vagy jelezzék. A processzorok rendelkeznek egy állapotregiszterrel, amely flag-ekből áll. Például, ha egy összeadás eredménye nem ábrázolható a célban, akkor aritmetikai túlcsordulást jelez.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. 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.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 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. 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, és a bitek jelölése független a numerikus indexüktől.

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.

C-ben a natív implementáció által meghatározott bitmezők létrehozhatók az ,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. , , (C99-ben), , (C23-ban) 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. 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 és bitenkénti műveletek kombinációival állíthatja be, tesztelheti és módosíthatja a mező bitjeit.

Példák C programozási nyelv Bitmező deklarálása C és C++ nyelven: // 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 = {"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 () bitmezőinek elrendezése a megvalósítás függvénye.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. 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; }

Rust Bár a Rust nyelvből hiányoznak a natív C stílusú bitmezők, ezt maszkok segítségével érik el. impl BoxProps { // Byte 0 const OPAQUE: u8 = 0b0000_0001; const FILL_COLOR_MASK: u8 = 0b0000_1110;

// Byte 1 const SHOW_BORDER: u8 = 0b0000_0001; const BORDER_COLOR_MASK: u8 = 0b0000_1110; const BORDER_STYLE_MASK: u8 = 0b0011_0000;

// Byte 2 const WIDTH_MASK: u8 = 0b0000_1111; const HEIGHT_MASK: u8 = 0b1111_0000; }

impl BoxProps { fn opaque(&self) -> bool { self.raw & Self::OPAQUE != 0

fn set_opaque(&mut self, v: bool) { self.raw = (self.raw & !Self::OPAQUE) | (v as u8);

fn fill_color(&self) -> u8 { (self.raw & Self::FILL_COLOR_MASK) >> 1

fn set_fill_color(&mut self, v: u8) { self.raw = (self.raw & !Self::FILL_COLOR_MASK) | ((v & 0b111) << 1);

fn width(&self) -> u8 { self.raw & Self::WIDTH_MASK

fn height(&self) -> u8 { (self.raw & Self::HEIGHT_MASK) >> 4

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. Példaként a 6502 processzor állapotregisztere 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 (á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 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. Számos nyelv támogatja a shift operátort (<<), ahol az 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 ( binárisan) és a 0x20 maszk-byte ( 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 Word Bitművelet

Jegyzetek

Fordítás

Kategória:Adatszerkezetek