Assembler - Wir sprechen AVRisch
Struktur eines Assemblerprogramms
Will man ein Assemblerprogramm schreiben, so muss man, wie bei jeder anderen Computersprache, einige Regeln einhalten. Bei Assembler sind diese aber recht übersichtlich. Im Grunde gibt es bei der Assemblerprogrammierung so gut wie keine Strukturen, wie sie in Hochsprachen bekannt sind.
Ein Assemblerprogramm besteht aus 3 verschiedenen Befehlsarten. Zum Ersten sind es die Assembler-Direktiven. Diese steuern den Assembler. Durch die Direktiven legt man z.B. fest, ab welcher Speicheradresse der Programmteil stehen soll, ob ein Listing erzeugt werden soll oder welche weitere Assembler-Dateien hinzu geladen werden.
Dann gibt es natürlich die Assembler-Befehle selbst. Als letztes seien noch die Labels, oder zu Deutsch, Sprungmarken erwähnt.
Ergänzen kann man schlussendlich sein Programm noch mit Kommentaren, welche aber für das Programm selbst unwichtig sind.
Assembler-Direktiven
Möchte man dem Assembler bestimmte Informationen mitteilen oder Einstellungen vornehmen, so kann man dies mit Hilfe von Direktiven tun. Diese Steuerbefehle beginnen Grundsätzlich mit einem Punkt. Hier sollen einige aufgezeigt werden. Diese sind vom AVR-Studio. Andere Assembler könnten evtl. etwas andere Direktiven haben. Hierzu dann bitte die Hilfe des Programms in Anspruch nehmen.
Hier ist auch nur eine kleine Auswahl der verfügbaren Steuerwörter gezeigt. Weitere findet man in der Online-Hilfe.
.db / .dw
Oft werden Datentabellen oder Texte benötigt. Diese können dann mit .db oder .dw im Flash oder EEPROM abgelegt werden. .db legt die Daten Byteweise ab während .dw immer Wortweise ablegt.
.def
Mit .def ist es Möglich, den Registern eine neue Bezeichnung zu geben. So kann man sich Register, welche nur für eine bestimmte Aufgabe verwendet werden, eine leicht zu merkende Bezeichnung geben.
.equ
In Assemblerprogrammen benötigt man immer wieder bestimmte Konstanten. Z.B. die gewählte Quarzfrequenz, die Größe des Arbeitsspeichers, bestimmte Steuerwörter von der Peripherie usw.
.include
Sollen andere Assemblerdateien hinzugefügt werden, so wird dieser Befehl verwendet. In der Regel findet man diesen Befehl gleich in der ersten Zeile des Programms. Hiermit wird die Definitionsdatei für den jeweiligen AVR geladen, damit der Assembler weiß, welche IO-Elemente etc. der AVR hat.
.org
Mit .org wird die aktuelle Programmadresse festgelegt. Trifft der Assembler auf diesen Befehl, werden die weiteren Assembler-Befehle ab dieser Adresse abgelegt.
Assembler-Befehle
Das Wichtigste beim Assembler sind natürlich die Assembler-Befehle. Assembler-Befehle beim AVR belegen im Programmspeicher immer 2 oder 4 Byte. Es gibt Befehle, welche nur aus einem einfachen Befehl, aus einem Befehl mit einem Parameter oder auch aus 2 Parameter besteht.
Ein Befehl mit 2 Parametern sieht z.B. so aus:
ldi r16,123
Der Assembler-Befehl, auch Mnemonic genannt, bestimmt, was der AVR tun soll. Der erste Parameter stellt das Ziel dar, worin das Operationsergebnis gespeichert werden soll. Der zweite Parameter ist die Datenquelle. Während der erste Parameter immer ein Register oder eine Speicherstelle ist, kann der 2. Wert ziemlich unterschiedlich sein.
Das Einfachste sind Konstanten. Beim AVR haben diese immer 8 Bit. Dezimalzahlen können direkt angegeben werden. Möchte man Hexadezimalzahlen angeben, so muss '0x' vorangestellt werden. Bei Binärzahlen ein '0b'. Also z.B. 0xFA oder 0b10010100. Auch einzelne Ascii-Zeichen können angegeben werden. Dies geschieht dann durch Hochkommas, z.B.: 'A'.
Damit man sein entworfenes Assembler-Programm auch nach längerer Zeit noch versteht, kann man Kommentare einfügen. Sobald der Assembler auf ';' trifft, wird der Rest der Zeile ignoriert.
Labels / Sprungmarken
Wie in jedem Programm muss man auch in Assembler hin und wieder zu anderen Programmteilen springen. In Assembler kann man natürlich die anzuspringende Speicheradresse direkt angeben. Nur ist dies sehr mühselig und des Weiteren für die spätere Programmwartung nicht sehr Hilfreich. Hierbei helfen Labels oder auch Sprungmarken.
Labels werden am Anfang der Zeile vor dem Programmabschnitt gesetzt, welche man in einem anderen Programmpunkt anspringen möchte. Ein Label muss mit ':' abgeschlossen werden, da sonst der Assembler das Label als Befehl ansieht.
Sprungmarken können bis zu 31 Zeichen lang sein. Nun kann man, anstelle der Adresse, die Sprungmarke einsetzen. Also z.B. anstatt 'call 0x04B8' können wir nun 'call wait5ms' schreiben.