Kommunikation.
Unter Maschine wird in diesem Zusammenhang die
Rechenmaschine, also der Mikrocontroller oder PC, verstanden!
Nicht also Omas Nähmaschine, eher eine NC-Werkzeugmaschine.
Plattformunabhängig bedeutet, dass sich die beteiligten
Maschinen keine »Gedanken« über die Eigenheiten der jeweils anderen
Maschine machen brauchen (und auch sollen).
Da die Byte-Anordnung von Mehr-Byte-Zahlen zwei Interpretationen kennt,
nämlich „Intel“ und „Motorola“, macht man die Übertragung von Zahlen oftmals mit
ASCII-Zeichen. Auch vermeidet man so »verbotene« oder unbeliebte Zeichen,
wie XON/XOFF und NUL. |
1. Binärdarstellung
Zahlen werden in mehr oder weniger Bytes gespeichert.
Hier werden zur Vereinfachung nur 8-bit-Controller betrachtet.
Bytes | Anzahl unterschiedlicher Werte
|
---|
1 | 28 = 256
|
2 | 216 = 65 536
|
3 | 224 = 16 777 216
|
4 | 232 = 4 294 967 296
|
Die Speicherplätze, in denen die Bytes von Mehr-Byte-Zahlen abgelegt werden,
ist völlig schnuppe; sie können auch einzeln verstreut liegen, und das ist
bisweilen sogar zweckmäßig!
Üblich ist jedoch die Ablage in aufeinander folgenden Bytes, in zwei Weisen:
Name: | Little Endian („Intel-Notation“) | Big Endian („Motorola-Notation“)
|
---|
Reihenfolge: | niedrigstes Byte zuerst | höchstes Byte zuerst
|
---|
Vorteil: | kleinerer Datentyp liegt auf gleicher Adresse | Hex-Dump problemlos lesbar
|
---|
Nachteil: | Hex-Dump byteweise verdreht | Adress-Offset bei Zugriff auf kleineren Datentyp
|
---|
Vertreter: | |
---|
Das Problem ist nur, dass es diese beiden Weisen überhaupt gibt!
Achtung: In welcher Weise der Assembler große Konstanten bei dw
und dd ablegt legt oft die Entscheidung schon fest! Hilfe konsultieren!
Man kann es IMHO nie als Programmierer festlegen.
Es sei denn, man benutzt Makros zur Ablage der Konstanten.
Hinweis: Mit Mikrocontroller-Assembler ist es absolut legitim und zweckmäßig,
auch 3-Byte-Zahlen zu verwenden, die es in Hochsprachen nicht gibt!
»Krumme« Bitbreiten und das Verwenden von Nibbles (= Halb-Bytes, Tetraden)
wie bspw. bei FAT12 sind dagegen grundsätzlich abzuraten.
Es ist völlig schnuppe, was mit den 256 unterschiedlichen Werten eines Bytes
angestellt wird. Üblich sind jedoch zwei, äh, drei Interpretationsweisen:
- vorzeichenlose Zahl: 0..255
- vorzeichenbehaftete Zahl im Zweierkomplement: –128..+127
- ASCII-Steuerkode im Bereich 0..31, ASCII-Zeichen im Bereich 32..127,
Sonderzeichen im Bereich 128..255
(Je nach Problemkreis wählen! Nicht zwangweise DOS- oder Windows-kompatibel!)
Die Interpretation als Zeichen wird im folgenden ausgelassen!
Dabei können Zeichen wiederum vorzeichenbehaftet (Sonderzeichen –128..–1)
oder vorzeichenlos (wie oben) interpretiert werden.
Sonderzeichen sind plattform-abhängig!
Machen Sie bei der Maschine-Maschine-Kommunikation zwei,
drei Schritte nach vorn und legen Sie UTF-8 fest! |
Vom Mikrocontroller, speziell dessen Statusregister (Flags), wird man bei
diesen beiden »Zahlen-Denkweisen« bestens unterstützt.
2. Zweierkomplement (ZWK)
Das ZWK gibt es nur in der Binärdarstellung.
Besser, man charakterisiert das ZWK über die angenehmen
Eigenschaften, anstatt es zu definieren:
- Das höchstwertige Bit ist das Vorzeichenbit.
- Es gibt nur eine Null, und diese ist »positiv«.
- Ist das Vorzeichenbit Null, ist das ZWK gleich der vorzeichenlosen Zahl.
- Ist das Vorzeichenbit Eins, ist die Zahl negativ (also kleiner Null).
Der Betrag ergibt sich durch Subtraktion von Null
oder dem Einerkomplement (logische Negation aller Bits, »CPL«), gefolgt von Dekrement.
(Häufig steht dafür der Befehl »NEG« zur Verfügung.)
- Addition, Subtraktion und Vergleich sind gegenüber vorzeichenlosen Zahlen unverändert!
Lediglich andere Flags sind auszuwerten!
Wichtig: Man muss die passenden Flags auswerten!!
Flag-Auswertung ist die Domäne des Vergleichs.
Tipp: Man geize nicht mit Bits. Zum bequemen Rechnen nutzt man den
Zahlenbereich maximal bis zur Hälfte aus, also ±63 für Bytes, ±16383 für 2 Bytes
usw. Notfalls spendiert man ein Byte mehr. Es kostet weniger als manch
umständliche Flag-Auswertung.
3. Vorzeichen+Betrag
Weil man mit Zweierkomplement nicht direkt multiplizieren/dividieren kann
(Ausnahme: ATmega, C166), ist die Vorzeichen+Betrags-Darstellung
zweckmäßig.
Für das Vorzeichen wähle man einen Platz im bitadressierbaren Speicher!
Das Betrags-Byte dafür zu verwenden führt zu lästigen Maskierungsoperationen.
Es wird letztlich mit 9-Bit-Zahlen, 17-Bit-Zahlen usw. operiert.
4. Festkommazahlen
Festkommazahlen sind nichts anderes als Ganzzahlen, bei denen man sich
ein Komma an einer festen Position denkt.
Genau so, als würde man Zimmer oder Grundstücke in Millimetern messen,
nur um gebrochene Meter zu vermeiden.
Dezimale oder binäre Teilung hängt davon ab, wie man die Zahl
schließlich dem Menschen darstellt. Will man bspw. „4,25 m“
ausgeben, rechnet man mit Zentimetern.
Für alle internen Operationen, bei der man zunehmende Rundung
vermeiden will, nimmt man binäre Teilung. Will man bloß „4,2 m“ ausgeben,
(also ganze Dezimeter), aber intern genauer rechnen,
nehme man nicht hundertstel Dezimeter (=Millimeter),
sondern 1/256 Dezimeter. Das ergibt 1 Byte Nachkommastellen, nur zum
Rechnen. Zur Ausgabe lässt man dieses Byte einfach weg!
5. Gleitkommazahlen
„Gleitpunktzahlen“ und „Fließkommazahlen“ sind Fehlübersetzungen!
Für solche Zahlen gibt es genormte IEEE-Darstellungen.
Wird Binärdatenaustausch zum PC gewünscht, ist man auf diese festgelegt.
Das wird selten der Fall sein: Man backe also eigene Brötchen!
Und beachte hierzu:
- Vermeide Gleitkommazahlen! Benutze Festkommazahlen.
- Vermeide Gleitkommazahlen! Benutze genügend lange Festkommazahlen.
- Vermeide Gleitkommazahlen! Benutze Tabellen.
- Benutze ein eigenes Gleitkommaformat.
Das eigene Gleitkommaformat sollte in etwa den IEEE-Format
entsprechen; Vorzeichenbits steckt man aber besser in dedizierte Bit-Register.
Baustelle!
Geplant sind downloadbare Makros für o. g. Mikrocontroller für
Gleitkomma-Grundrechenoperationen.
haftmann#software, 9.8.2004