Das Erlernen der Assemblersprache ist die ultimative Entscheidung zum erfolgreichen Programmieren eines Microcontrollers. Keine Hochsprache bietet mehr Kontrolle über die Maschine, bessere Performance oder effizientere Ressourcennutzung. Diese Seite bietet eine kleine Anleitung für die ersten Schritte in Assembler für 8051-kompatible Controller. Voraussetzung ist die rudimentäre Kenntnis einer beliebigen Programmiersprache, da grundlegende Kenntnisse über Schleifen, Variablen und Verzweigungen als bekannt angenommen werden. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Befehlsliste |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Was ist ein Assembler? |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Compiler transformieren ein Hochsprachen-Programm, also einen Quelltext, enthalten in einer einfachen Textdatei, in ein Maschinenprogramm, das die Recheneinheit direkt ausführen kann. Dabei wird der Quelltext analysiert und die komplexen Hochsprachenbefehle in die viel einfacheren Maschinensprache umgesetzt, ohne den Programmierer dabei mit Details zu konfrontieren oder Eingriffsmöglichkeiten zu gestatten. Im Gegensatz zu Hochsprachen-Programmen besteht ein Assemblerprogramm nicht aus komplexen, mächtigen Befehlen, sondern aus einfachen Mnemonics genannten Kürzeln, die eine direkte Entsprechung in der Maschinensprache des Rechenwerks besitzen. |
Darum wird ein Assemblerprogramm bei der Umwandlung in Maschinensprache nicht analysiert und transformiert, sondern im Wesentlichen nur mit einer simplen Umsetzungstabelle in Maschinensprache überführt. Dieser Prozess ist so einfach und direkt, dass man ihn notfalls sogar per Hand ausführen könnte. Das Mnemonic 'NOP' beispielsweise wird in Maschinensprache mit der Zahl 90h kodiert, der Assembler ersetzt also einfach NOP durch 90h.
Dadurch hat der Assembler-Programmierer die volle Kontrolle über
die Maschine, ohne den Zwischenschritt über einen Compiler.
Das kann auch ein Nachteil sein: es gibt keine Ausreden mehr für
abstürzende Programme, da kein Compiler mehr Fehler einbauen könnte, man ist
höchst selbst dafür verantwortlich :-)
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Bits und Bytes |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Bits sind auch bei Microcontrollern die kleinste darstellbare Informationseinheit. Sie besitzen zwei Zustände: 0 und 1. Werden Bits auf die Ausgänge des Controllers geschrieben, so entsprechen 0V und zumeist 5V diesen beiden Zuständen. Jeweils 8 dieser Bits können zu einem Byte zusammengefasst werden. Damit sind dann Zahlen von 0 bis 28-1, also 0 bis 255, dargestellt werden. Um größere Zahlen abbilden zu können, müssen dann mehrere dieser Bytes logisch zusammengefasst werden. 2 Byte oder 16 Bit können schon Zahlen von 0 bis 2562-1 bzw. 216-1 oder 65535 darstellen. |
Dieses Zusammenfassen mehrerer Bytes wird von Hochsprachen wie C oder BASIC
automatisch erledigt, in Assembler ist dies Aufgabe des Programmierers. Dafür
ist es in Assembler aber auch leicht möglich, für die jeweilige
Aufgabe optimale Algorithmen zu verwenden und somit die Performance im
Vergleich zu C- oder gar BASIC-Programmen um ein Vielfaches zu steigern
und gleichzeitig den dafür erforderlichen Speicherplatz sehr gering zu halten.
So kennt C üblicherweise keinen 24 Bit-Datentyp, obwohl er an
vielen Stellen gut zu gebrauchen ist.
zurück zum Anfang |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Zahlenspiele |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
In der Programmiererei werden verschiedene Zahlensysteme angewendet. Dies hat nicht den Sinn, eventuell mitlesende Kollegen zu verwirren, sondern die Arbeit einfacher zu gestalten, da sich manche Zusammenhänge durch das richtige Zahlenformat leichter erschließen. Über das dezimale Zahlensystem ist nicht viel zu sagen - es ist jedem seit der Grundschule geläufig. Auch der Assembler kann damit umgehen. Wenn eine Zahl keinen nachgestellten Buchstaben als Anhängsel hat, dann ist damit |
eine Zahl des Dezimalsystems gemeint. Das binäre Zahlenformat besitzt die Basis 2. Daher werden nur die Ziffern 0 und 1 zur Darstellung beliebiger Werte verwendet. Dies funktioniert völlig analog zum gewohnten dezimalen Zahlensystem: Ziffern, die eine Stelle weiter links stehen, haben eine um eine Potenz höhere Wertigkeit als ihr rechter Nachbar. Der Unterschied zum Dezimalsystem besteht nun darin, dass diese Potenz die Basis 2 und nicht wie gewohnt 10 hat. |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Eine 21 des Dezimalsystems kann daher so in das Binärsystem umgerechnet werden: 21 = 2x101+ 1x100 = 20 + 1 = 16 + 0 + 4 + 0 + 1 = 1x24 + 0x23 + 1x22 + 0x21 + 1x20 = 10101b |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Das Binärsystem ist also von der Aussage her völlig identisch mit dem Dezimalsystem - beides sind nur Zahlen. Warum also sollte man sich umgewöhnen, wenn es sich mit Dezimalzahlen viel gewohnter rechnen läßt? Das Binärsystem hat einen ganz einleuchtenden Vorteil, wenn man einzelne Bits gezielt manipulieren möchte. Muss man beispielsweise den externen Interrupt 1 einschalten und dazu die Bits 2 und 7 im IE-Byte setzen, so kann man entweder mühsam ausrechnen, dass man den Wert 132 nach IE schreiben muss, oder einfach 10000100b verwenden. Damit Binärzahlen von anderen Zahlenformaten unterschieden werden können, stellt man ihnen ein kleines 'b' nach. Das Hexadezimalsystem ist ebenso wie das Binärsystem ein Zahlenformat mit einer anderen Potenz als Basis: der 16. Weil die gewohnten Ziffern von 0 bis 9 nicht mehr ausreichen, um alle Zahlen abzubilden, geht es im Hexadezimalsystem nach der 9 mit A-B-C-D-E-F weiter. |
Um Hexadezimalzahlen von anderen Zahlenformaten sowie Symbolen abzugrenzen, stellt man Hexadezimalzahlen eine '0' voran, sofern die erste Ziffer im Intervall von A bis F liegt, und ein kleines 'h' nach. Würde man auf die vorangestellte 0 immer verzichten, käme es zu Verwechslungen mit Labeln oder Assemblersymbolen, die ja schließlich auch aus Buchstaben und Zahlen bestehen dürfen, nur eben nicht mit einer Ziffer von 0 bis 9 beginnen.
Das Hexadezimalsystem hat dann Vorteile, wenn man ein Byte als zwei Hälften
(in Fachkreisen 'Nibbles' genannt) betrachten will: in diesem Falle steht jede
Hexadezimalziffer für 4 Bit. Wenn man hexadezimal 12h angibt, erkennt man mit
ein wenig Übung sofort, dass in
dieser Zahl die Bits 4 und 1 gesetzt sind, bzw. im 1. Nibble das 2. Bit und im 2. Nibble das 1. Bit.
Aus der dezimalen 18, die die Entsprechung von 12h ist, ist das nur durch eine Rechnung herauszufinden.
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Die Umrechnung der 21 in das Hexadezimalsystem erfolgt analog zur Umrechnung in das Binärsystem, nur mit anderen Faktoren: 21 = 2x101+ 1x100 = 20 + 1 = 16 + 5 = 1x161+ 5x160 = 15h |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Adressierung und Konstanten |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Der Assembler für Microcontroller-Dialekte kennt mehrere Möglichkeiten, um Zahlen anzugeben bzw. Speicherstellen zu adressieren, die alle sorgfältig unterschieden werden müssen:
|