Materialien zum Unterricht

Bitmanipulationen

Setzen eines Bit

Eine typische Aufgabe sieht so aus: In einem Register sind die Bits 0 und 1 gesetzt:

Nun soll das Bit 5 noch auf 1 gesetzt werden, ohne dass sich die anderen Bits ändern.

Dazu wird die Bitfolge des Registers über die ODER-Verknüpfung mit dem gewünschten Bit vereinigt.

ODER-Verknüpfung

Bei der ODER-Verknüpfung zweier Bits erhält man außer dem Fall, dass beide 0 sind, immer eine 1.

In unserem Beispiel wird das Register mit einer Bitfolge ODER verknüpft, in der das gewünschte Bit, also das Bit 5, gesetzt ist.

In C sieht das so aus:

Register |= (1<<5)

Was bedeutet das?

Fangen wir hinten an. Die Konstruktion (1<<5) schiebt in einer Bitfolge, die aus Nullen besteht, eine 1 um 5 Bitpositionen von rechts nach links. Es wird also aus 00000000 eine Folge 00100000. (Achtung: (1<<0) schiebt eine 1 an die äußerste rechte Seite der Bitfolge)

Diese Bitfolge wird mit dem Inhalt des Registers ODER verknüpft. Die ODER-Verknüpfung wird durch den Bitoperator | realisiert.

Damit das Ergebnis zum Schluss wieder im Register steht, muss noch das = eingefügt werden.

Löschen eines Bit

Die Aufgabe kann so aussehen: In einem Register sind die Bits 0, 1 und 5 gesetzt.

Das Bit 5 soll gelöscht, also auf 0 gesetzt werden.

Dazu wird die UND-Verknüpfung benutzt.

UND-Verknüpfung

Bei der UND-Verknüpfung erhält man als Ergebnis nur dann eine 1, wenn beide Bits ebenfalls 1 sind.

Um das Bit 5 zu löschen, muss eine UND-Verknüpfung mit einer Bitfolge erfolgen, die außer an der Stelle von Bit 5 eine 1 hat:

In C sieht das so aus

Register &= ~(1<<5) 

Was bedeutet das?

(1<<5) ist klar, es wird eine Bitfolge erzeugt, die an der Stelle Bit 5 eine 1 hat. Ziel war aber, eine 0 dort hin zu stellen. Deshalb wird die Bitfolge durch das Zeichen ~ negiert. Das bedeutet, dass aus jeder 1 eine 0 und aus jeder 0 eine 1 wird. Damit steht an der gewünschten Stelle eine 0.

Nun wird diese Bitfolge durch & mit dem Registerinhalt UND verknüpft und durch das = dem Register wieder zugewiesen.

Ein Bit togglen

toggle bedeutet hin- und herschalten. Ist ein Bit 0, wird es eine 1 und umgekehrt. Ein einfaches Negieren geht nicht, da das ja auf das gesamte Register angewandt wird. Es soll aber nur ein Bit verändert werden, alle anderen bleiben erhalten.

Eine Lösung wäre das Setzen und Löschen des Bits.Dazu müsste man aber vorher fragen ob es gesetzt oder nicht gesetzt ist.

Aufgabe: Das Bit 5 ist gesetzt. Nach der nächsten Aktion soll dieses Bit 0 sein.

Die Aufgabe kann mit der Exclusiv-ODER-Verknüpfung gelöst werden.

Exclusiv-ODER-Verknüpfung

Das Ergebnis ist nur dann 1, wenn entweder das eine oder das andere Bit 1 ist. Sind beide Bits gleich, ergibt das immer eine 0.

Durch die Exclusiv-ODER-Verknüpfung wird nur aus dem Bit 5 aus der 1 eine 0.

Jetzt wird auf das Ergebnis wieder die Exclusiv-ODER-Verknüpfung angewandt:

Es funktioniert.

In C sieht das so aus:

Register ^= (1<<5) 

Das Zeichen ^ bewirkt die Exclusiv-ODER-Verknüpfung. Alles andere ist klar.

Sollen mehrere Bits verändert werden, kann man schreiben:

Register ^= (1<<5) | (1<<4) 

Jetzt werden Bit 4 und Bit 5 verändert.

Prüfen, ob ein Bit gesetzt ist

Es soll geprüft werden, on in einem Register ein bestimmtes Bit gesetzt ist. Das wird z.B. verwendet, um ein Port, an dem ein Schalter angeschlossen ist ist, abzufragen und das Programm je nach Schalterstellung verzweigen zu lassen. Also: Schalter gedrückt: mache was; Schalter nicht gedrückt: mache was anderes oder nichts.

Die Verzweigung wird durch if() realisiert. In der Klammer kann eine 1 oder eine 0 stehen. Diese binären Werte können z.B. durch einen Vergleich erzeugt werden.

Ist eine Aussage wahr, liefert sie 1, ansonsten eine 0.

  wahre Aussage (1) falsche Aussage (0)
x=3, y=4 ist x < y
if (x<y)
ist x = y
if (x==y)
ist x=3
if (x==3)
ist y nicht 4
if (y != 4)

Will man prüfen, ob ein Bit gesetzt ist, verwendet man wieder die UND-Verknüpfung.

Es soll die Bitfolge im Register auf ein gesetztes Bit 4 getestet werde. Dazu wird das Register mit einem gesetzten Bit 4 UND verknüpft.

Ist im Register das Bit 4 gesetzt, liefert die Verknüpfung eine 1, ansonsten 0.

 

In der if-Anweisung sieht das so aus (es wird das Register SCHALTER_PIN geprüft werden):

if (SCHALTER_PIN & (1 << 4)) {
     Anweisungen für: Bit war gesetzt
} else { 
     Anweisungen für: Bit war nicht gesetzt

}

Die if-Abfrage kann z.B. auch so auusehen:

if (SCHALTER_PIN & (1 << PINC0)) {...

Dann ist der Schalter am Port C, PIN 0 angeschlossen und dieser wird auf 0 oder 1 geprüft.

Die letzte Anweisung kann auch mit Hilfe des bereits vorhandenen Makros _BV(bit) geschrieben werden. _BV(bit) ersetzt (1 << bit)

if (SCHALTER_PIN & (_BV(PINC0)) {...