Bitpopelei
Erstellt: 2008-10-25 • Letzte Änderung: 2008-10-25 [vor 15 Jahren, 11 Monaten, 21 Tagen]
Der Name ist Programm; hier dreht sich alles um Binär- und Hexadezimalzahlen,
um Verknüpfungen und Konvertierungen, um Logikgatter und Ähnliches. |
Unentbehrlich für Entwickler, die hardwarenah - sei es auf dem Mikrocontroller oder dem PC - programmieren und sich mit solchen Dingen herumschlagen müssen.
Beispielcodes gibt es in AVR-Asm, x86-Asm, C, FreeBASIC und PHP.
Dez, Hex und Bin
Darstellungsweisen von Dez, Hex und Bin:Dez | Hex | Bin | |
AVR-Asm | 23 | 0x17 / 0h17 | 0b10111 |
x86-Asm | 23 | 0x17 / 0h17 | 0b10111 |
C | 23 | 0x17 | 0b10111 |
FreeBASIC | 23 | &H17 | &B10111 |
PHP | 23 | 0x17 | bindec('10111') |
Die Zahlen 0 bis 47 in Dezimal, Hexadezimal und Binär:
|
|
|
Nach oben
Bits und Bytes
Tabelle der Byte-Vielfachen:Nibble | 4 Bits | 1/2 Byte |
Byte | 8 Bits | 1 Byte |
Word | 16 Bits | 2 Bytes |
DWord | 32 Bits | 4 Bytes |
QWord | 64 Bits | 8 Bytes |
Bits in einem Byte:
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
MSB | LSB |
LSB = Least Significant Bit
Nach oben
Endianness
Als Endianness bezeichnet man die Reihenfolge der Bytes in einem Word bzw. in Word-Vielfachen.Little Endian:
Intel-Format. Kleines Ende zuerst. Das niederwertige Byte steht am Anfang.Byte 1 | Byte 0 | ||||||||||||||
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
MSB | LSB |
LSB = Least Significant Byte
Big Endian:
Motorola-Format. Großes Ende zuerst. Das höherwertige Byte steht am Anfang.Byte 1 | Byte 0 | ||||||||||||||
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
LSB | MSB |
LSB = Least Significant Byte
Nach oben
Logikgatter
Wahrheitstabellen für die gebräuchlichsten Logikgatter.List of 7400 series integrated circuits - Wikipedia |
NOT | ||
A | Y | |
0 | 1 | |
1 | 0 | |
|
|
|
|
|
|
Nach oben
Bitoperationen
Einzelnes Bit setzen
Das im Byte zu setzende Bit wird in der Maske gesetzt.Die Maske entspricht dem Wert 2 ^ bit.
Dann wird die Maske mit dem Byte OR-verknüpft.
AVR-Asm |
Nur für Register:ldi r16, 0b00001000 ; Das Byte sbr r16, (1 << 7) ; Das Bit Nr. 7 wird im Byte gesetzt Nur für Ports: sbi PORTA, 7 ; Das Bit Nr. 7 wird im Port PORTA gesetzt |
x86-Asm |
mov al, 7 ; Das zu setzende Bit mov ah, 0b00001000 ; Das Byte or al, ah ; Das Bit wird im Byte gesetzt |
C |
unsigned char bit = 7; // Das zu setzende Bit unsigned char x = 0b00001000 | (1 << bit); // Das Bit wird im Byte gesetzt oder alternativ unsigned char bit = 7; // Das zu setzende Bit unsigned char x = 0b00001000; // Das Byte x |= (1 << bit); // Das Bit wird im Byte gesetzt |
FreeBASIC |
DIM AS INTEGER bit = 7 ' Das zu setzende Bit DIM AS INTEGER x = &B00001000 OR (bit ^ 2) ' Das Bit wird im Byte gesetzt |
PHP |
$bit = 7; // Das zu setzende Bit $x = 0b00001000 | (1 << $bit); // Das Bit wird im Byte gesetzt oder alternativ $bit = 7; // Das zu setzende Bit $x = 0b00001000; // Das Byte $x |= (1 << $bit); // Das Bit wird im Byte gesetzt |
In C ist folgendes Makro hilfreich:
#define set_bit(var, bit) ((var) |= (1 << (bit)))
Einzelnes Bit löschen
Das zu löschende Bit wird in der Maske gelöscht.Alle übrigen Bits in der Maske werden gesetzt.
Die Maske entspricht dem negierten Wert 2 ^ bit, also 255 - (2 ^ bit).
Dann wird die Maske mit dem Byte AND-verknüpft.
AVR-Asm |
Nur für Register:ldi r16, 0b00001000 ; Das Byte cbr r16, (1 << 7) ; Das Bit Nr. 7 wird im Byte gelöscht Nur für Ports: cbi PORTA, 7 ; Das Bit Nr. 7 wird im Port PORTA gelöscht |
x86-Asm |
mov al, !(7) ; Aus dem zu löschenden Bit (in Klammern) die Maske erstellen mov ah, 0b00001000 ; Das Byte and al, ah ; Das Bit wird im Byte gesetzt |
C |
unsigned char bit = 7; // Das zu löschende Bit unsigned char x = 0b00001000 & ~(1 << bit); // Das Bit wird im Byte gelöscht oder alternativ unsigned char bit = 7; // Das zu löschende Bit unsigned char x = 0b00001000; // Das Byte x &= ~(1 << bit); // Das Bit wird im Byte gelöscht |
FreeBASIC |
DIM AS INTEGER bit = 7 ' Das zu löschende Bit DIM AS INTEGER x = &B00001000 AND NOT (bit ^ 2) ' Das Bit wird im Byte gelöscht |
PHP |
$bit = 7; // Das zu löschende Bit $x = 0b00001000 & ~(1 << $bit); // Das Bit wird im Byte gelöscht oder alternativ $bit = 7; // Das zu löschende Bit $x = 0b00001000; // Das Byte $x &= ~(1 << $bit); // Das Bit wird im Byte gelöscht |
In C ist folgendes Makro hilfreich:
#define clear_bit(var, bit) ((var) &= (unsigned)~(1 << (bit)))
Mehrere Bits setzen
Alle im Byte zu setzenden Bits werden in der Maske gesetzt.Dann wird die Maske mit dem Byte OR-verknüpft.
Byte | 0b10001000 | |||
OR | 0b10101010 | Ergebnis | ||
Maske | 0b00100010 |
AVR-Asm |
ldi r16, 0b10001000 ; Das Byte wird in r16 geladen ori r16, 0b00100010 ; Das Byte wird mit der Maske OR-verknüpft |
x86-Asm |
mov al, 0b10001000 ; Das Byte in al laden or al, 0b00100010 ; Das Byte wird mit der Maske OR-verknüpft |
C |
unsigned char x = 0b10001000 & 0b00100010; // Das Byte wird mit der Maske OR-verknüpft oder alternativ unsigned char x = 0b10001000; // Das Byte wird in x geladen x |= 0b00100010; // Das Byte wird mit der Maske OR-verknüpft |
FreeBASIC |
DIM AS INTEGER x = &B10001000 OR &B00100010 ' Das Byte wird mit der Maske OR-verknüpft |
PHP |
$x = 0b10001000 & 0b00100010; // Das Byte wird mit der Maske OR-verknüpft $x = 0b10001000; // Das Byte wird in $x geladen $x |= 0b00100010; // Das Byte wird mit der Maske OR-verknüpft |
Mehrere Bits löschen
Alle zu löschenden Bits im Byte werden in der Maske gelöscht.Alle übrigen Bits in der Maske werden gesetzt.
Dann wird die Maske mit dem Byte AND-verknüpft.
Byte | 0b11110010 | |||
AND | 0b11010010 | Ergebnis | ||
Maske | 0b11011111 |
AVR-Asm |
ldi r16, 0b11110010 ; Das Byte wird in r16 geladen andi 16, 0b11011111 ; Das Byte wird mit der Maske AND-verknüpft |
x86-Asm |
mov al, 0b11110010 ; Das Byte wird in al geladen and al, 0b11011111 ; Das Byte wird mit der Maske AND-verknüpft |
C |
unsigned char x = 0b11110010 & 0b11011111; // Das Byte wird mit der Maske AND-verknüpft oder alternativ unsigned char x = 0b11110010; // Das Byte wird in x geladen x &= 0b11011111; // Das Byte wird mit der Maske AND-verknüpft |
FreeBASIC |
DIM AS INTEGER x = &B11110010 AND &B11011111 ' Das Byte wird mit der Maske AND-verknüpft |
PHP |
$x = 0b11110010 & 0b11011111; // Das Byte wird mit der Maske AND-verknüpft oder alternativ $x = 0b11110010; // Das Byte wird in $x geladen $x &= 0b11011111; // Das Byte wird mit der Maske AND-verknüpft |
Alle Bits Nullsetzen
Ein alter Assembler-Trick:xor al, al
- Löscht alle Bits in al.Funktioniert natürlich mit allen Registergrößen.
Bits Invertieren
Die Bits werden mit dem für die Programmiersprache spezifischen Befehl invertiert.AVR-Asm |
Register:
ldi r16, 0x23 ; Das zu invertierende Byte com al ; Byte invertieren Konstante: ldi 16, !0x23 ; Den invertierten Wert von 0x23 in r16 schreiben |
x86-Asm |
Register:
mov al, 0x23 ; Das zu invertierende Byte not al ; Byte invertieren Konstante: mov al, !0x23 ; Den invertierten Wert von 0x23 in al schreiben |
C |
unsigned char x = ~0xff;<br> |
FreeBASIC |
DIM AS INTEGER x = NOT &HFF |
PHP |
$x = ~0xff; |
Nach oben
Konvertierungen
C / C++
Most Significant Word / Least Significant Word:#define msw(var) (((var >> 16) & 0xffff)) #define lsw(var) ((var & 0xffff))
Most Significant Byte / Least Significant Byte:
#define msb(var) ((var >> 8) & 0xff) #define lsb(var) ((var & 0xff))
Most Significant Nibble / Least Significant Nibble:
#define msn(var) ((var >> 4) & 0xf) #define lsn(var) ((var & 0xf))
PHP
String zu Hexadezimal:function str2hex($str) { $hex = ""; for ($i = 0; $i < strlen($str); $i++) { $hex .= str_pad(dechex(ord($str[$i])), 2, 0, STR_PAD_LEFT); } return $hex; }
Hexadezimal zu String:
function hex2str($hex) { $str = ""; for ($i = 0; $i < strlen($hex); $i += 2) { $str .= chr(hexdec(substr($hex, $i, 2))); } return $str; }
Nach oben