Assembler

Prozessoren verstehen nur die binäre Sprache. Eine Folge von Nullen und Einsen gibt ihnen Anweisungen, was zu tun ist. Soll z.B. die Zahl H13 (H13 = 19 dezimal) in das Hauptregister des PIC 16C84 geladen werden, so muss der Prozessor in seinem Programmspeicher die Anweisung 0011 0000 0001 0111 finden. Man kann sich ausrechnen, wie viel derartige Kombinationen von Nullen und Einsen und damit auch wie viel Fehlerquellen möglich sind. Eine erste Vereinfachung besteht darin, die Zahlen im Binärsystem zu besser überschaubaren Zahlen im Hexadezimalsystem (kurz zu Hexzahlen) zusammenzufassen. Die Anweisung wird dadurch schon viel überschaubarer : H3013. Der Vorteil der Hexzahlen besteht darin, dass man immer vier Binärstellen zu einer Hexstelle zusammenfassen kann und dass gleiche vierstellige Bitmuster auch immer gleiche Hexziffern bedeuten unabhängig davon, welches "Nibble" gerade gemeint ist. Dabei geht man von den niederwertigeren zu den höherwertigen Stellen, also von rechts nach links vor: B0011 0000 0001 0011 = H3013. Diese Art von Sprache, die der Rechner versteht, ist die sogenannte Maschinensprache. Je nach Art des Prozessors besteht sein Befehlssatz also aus einer Tabelle von Hexzahlen. Ohne weitere Hilfsmittel müsste man also eine Liste von Hexzahlen entwerfen, die dann ein Programm darstellen. Diese Zahlen würden dann in den Programmspeicher des Prozessors gebrannt. In der Hoffnung, dass man kein logischen und keine Eingabefehler gemacht hat, müsste der Prozessor jetzt seine Aufgabe erfüllen.

Nun haben Prozessoren aber oft Befehlssätze mit hundert und mehr Befehlen. Diese alle in einer Tabelle mit Hexzahlen nachzuschauen, ist recht mühsam. Man gibt deswegen jedem Maschinenbefehl ein Abkürzung, die wenigstens ahnen lässt, was der entsprechende Befehl bewirken soll. Das obige Beispiel würde bei 16C84 lauten: movlw 13. Wenn man ein wenig Englisch kann und sich in die Welt des Assemblers eingearbeitet hat, dann kann man sogar verstehen, was der Befehl bewirken soll: Move Literal into W 13. Zu Deutsch: Schiebe die Konstante 13 in das Work-Register (bei anderen Prozessoren Akkumulator genannt).

Solche Befehle nennt man Assemblerbefehle und den gesamten Umfang dieser Befehle die Assemblersprache des Prozessors. Sie hat einen Vorteil: Der Programmierer versteht sie besser allerdings auch einen gravierenden Nachteil: Der Prozessor versteht sie überhaupt nicht, d.h. man muss sie vor dem Brennen des Programms wieder in Maschinensprache übersetzen. Für diese sehr mühselige Arbeit setzt man spezielle Computerprogramme, sogenannte Assembler ein. Für die Familie der PICs wird ein Assembler und ein Simulator kostenlos angeboten.

Der Begriff 'Assembler' wird landläufig in zwei verschiedenen Bedeutungen gebraucht. Zum einen bezeichnet er das Programm, das die Übersetzung der Assembler- in die Maschinensprache übernimmt. Oft wird auch die Assemblersprache selber kurz Assembler genannt. Normalerweise führt das nicht zu Verwirrungen. Wenn man schon einen Assembler hat, so kann man sich das Programmieren eines Prozessor noch weiter vereinfachen. Unabdingbar fürs Programmieren sind sogenannte Register, d.h. Speicherstellen, in denen man Werte für Konstanten und Variablen unterbringen kann und die einfach zu adressieren sind. Wie in einer höheren Sprache kann man diesen Registern Namen zuweisen und sie später im Programm mit ihren Namen aufrufen. Wenn man diesen Registern jetzt auch noch sinnvolle Namen gibt, wie z.B. counter, so wird das Programm immer übersichtlicher. Nachdem man ein Register deklariert hat, setzt der Assembler überall im Programm, wo der entsprechende Name auftaucht, die korrekte Speicherstelle ein. Registernamen werden im Maschinencode mit definierten Adressen übersetzt.

Eine weitere Erleichterung, die einem der Assembler abnimmt, ist die Berechnung von Sprungadressen. Will man z.B. eine Schleife programmieren, so muss man unter bestimmten Voraussetzungen immer wieder an eine bestimmte Stelle des Programms verzweigen. Mit Papier und Bleistift wäre man also immer dabei, die Anzahl von Anweisungen auszurechnen, die bei einem Vorwärts- oder Rückwärtssprung übersprungen werden müssten. Zur Vereinfachung bietet der Assembler sogenannte Lables an, das sind Sprungmarken, die man mit sinnvollen Namen versehen kann. Bei einer Anweisung wie z.B. goto init wird anstelle von init die Adresse der auf das Label folgenden Anweisung gesetzt. Danach wird ausgerechnet, wie viele Speicherstellen zwischen der aufrufenden und der aufgerufenen Anweisung liegen.

Ohne vernünftige Fehlermeldung wäre die Programmier-Arbeit ziemlich lästig. Syntaxfehler, wie z.B. schlichte Tippfehler oder auch falsche Parameter bei einer Anweisung werden mit der entsprechenden Zeilennummer gemeldet. Doppelte bzw. fehlende Labels, sowie Überschreiben von Speicherbereichen durch unzulässige org-Anweisung werden auch gemeldet.

Zahlen werden standardmäßig als hexadezimale Zahlen verstanden: Der assemblerbefehl movlw 013 lädt den konstanten Wert H013 = D19=B00010011 in das Arbeitsregister. Möchte man explizit Zahlen im Dezimal- oder auch Binärsystem eingeben, so tut man das wie folgt: movlw B'0001011' oder movlw D'19'. Fangen Zahlen im Hexadezimalsystem mit den Ziffern 'A',..'F' an, so muss die Zahl mit einer führenden '0' geschrieben werden: also movlw 0A3.

Zurück

© Dietrich Praclik