Der AVR Assembler
Ein Assembler ist ein Programm, das die Maschinensprachebefehle zu einer Datei zusammensetzt, die in den Programmspeicher des Prozessors geladen werden kann. In diesem Beispiel wird der AVR Assembler 2, der im der AVR Entwicklungsumgebung enthalten ist, beschrieben.
Die Unterkapitel sind Assemblerdirektiven, Assembleroperationen und Makros.
Die hier gezeigten Assembleroperationen sind keineswegs vollständig, sondern dienen nur einem guten Start in die Maschinenspracheprogrammierung. Die vollständige Dokumentation des AVR-Assemblers ist in der Hilfe der Entwicklungsumgebung AVR-Studio zu finden.
Kommentare im AVR Assembler gehen zeilenweise mit ; oder // oder als Blockkommentar mit /* ... */
Groß- / Kleinschreibung ist dem AVR Assembler egal. Definiert man beispielsweise ein Label "Loop:", dann kann diese mit jmp loop oder jmp Loop oder JMP LOOP gleichermaßen angesprungen werden. Die Verwendung von Groß-/Kleinschreibung dient also nur dem Programmierer zur ggf. besseren Lesbarkeit.
Die Assembler-Direktiven fangen mit einem . an. Mit diesen Direktiven kann man z.B. Werte einem Schüsselwort zuweisen. Dies kann man beispielsweise für Konstanten und Variablen verwenden. Es können auch Programmteile abhängig von bestimmten Werten einbezogen, ausgeschlossen oder ausgetauscht werden.
.include mit .include kann eine externe Datei inkludiert werden.
.include "m48def.inc" ; Einbinden der Prozessordefinition für den ATMega48
.include "OLED-Display.asm" ; Einbinden eines Stücks Assembler-Programmcode. Dieser wird an genau der Stelle eingebunden, wo der .include Befehl steht.
.def mit .def kann einem Symbol (Begriff) ein Register zugewiesen werden. Damit kann Code lesbarer gestaltet werden, weil die Register Namen bekommen und nicht nur R0-R31 heißen.
.def Temp = R20 ;Setzt Temp als Synonym für das Register R20
ldi temp, 200 ; Verwendung des neu benannten Registers
.equ mit .equ kann einem Symbol (Begriff) ein Zahlenwert zugewiesen werden. Die kann direkt oder auch über eine Rechenoperation erfolgen.
.equ var=SRAM_START ;Setzt var auf den Anfang des SRAMS (das geht nur, wenn die Prozessordefinition bereits eingebunden wurde.
.org mit .org wird die Anfangsadresse (Origin) eines Speicherblocks definiert. Die Verwendung erfolgt zusammen mit .cseg oder .dseg
.cseg mit .cseg wird gekennzeichnet, dass alles Folgende in den Programm-Bereich (Code-Segment) des Prozessors geschrieben wird. Dies ist der Flash-Speicher. Man gibt zusätzlich mit .org noch die Adresse an, ab der in das Segment geschrieben wird.
.cseg ;es folgt ein Code-Segment
.org 0x0000 ; Das Codesegment startet bei Adresse 0x0000
jmp Start ;Erster Befehl im Code-Segment
.dseg mit .dseg wird gekennzeichnet, dass alles Folgende in den SRAM-Bereich (Data-Segment) des Prozessors geschrieben wird. Man gibt zusätzlich mit .org noch die Adresse an, ab der in das Segment geschrieben wird.
.dseg ;es folgt ein Data-Segment
.org SRAM_START ; Das Data-Segment startet Am Anfang des SRAMs.
Counter8: .byte 1 ;Die Variable Counter8 wird mit 1 Byte Länge im SRAM reserviert
Counter16: .byte 2 ;Die Variable Counter16 wird mit 2 Byte Länge im SRAM reserviert
.eseg mit .eseg wird gekennzeichnet, dass alles Folgende in den EEPROM-Bereich des Prozessors geschrieben wird. Man gibt zusätzlich mit .org noch die Adresse an, ab der in das Segment geschrieben wird.
.eseg ;es folgt ein EEPROM-Segment
.org 0x0000 ; Das Segment startet bei am Anfang des EEPROMS
.db 0,10,20,30,40,50,60,70 ;Definition von 8 Werten, die beim Programmieren in das EEPROM geschrieben werden sollen (=Initialisieren des EEPROMS)
.byte [n] mit .byte [n] wird im Daten-Segment ein Speicherbereich mit der Länge n reserviert. Wird die Direktive mit einem Label kommentiert, so können damit Variablen verschiedener Länge definiert werden.
.db mit .db wird an der Stelle, an der die Direktive steht, eine Folge an 2-Byte Wörtern definiert (Define Word). Diese Wörter können Zahlen von 0-65535 (auch hexadezimal oder binär) sein.. Die Direktive funktioniert im Code-Segment und im EEPROM-Segement. Mit dieser Direktive können z.B. Tabellen, Zeichenketten oder Grafikdaten im Programmspeicher abgelegt werden.
Im EEPROM können einzlene oder mehrere Bytes definiert werden. Im Flash-Speicher können immer nur Vielfache von 2-Byte definiert werden (=geradzahlige Anzahl an Bytes). Definiert man eine ungeradzahlige Anzahl, wird ein zusätzliches Füllbyte angehängt.
.db 100,105,110,115 ;Definition einer Zahlenfolge
.db 'H', 'a', 'l', 'l', 'o', ' ', 'W', 'e', 'l', 't' ; Definition einer Folge aus einzelnen Zeichen
.db "Hallo Welt" ;Definition einer Zeichenkette
.dw mit .dw wird an der Stelle, an der die Direktive steht, eine Folge an 16-Bit Wörtern definiert (Define Word). Diese Wörter können Zahlen von 0-65535 (auch hexadezimal oder binär) sein. Hiermit können z.B. 16-Byte Tabellen (auch Sprungtabellen für IJMP oder ICALL) erstellt werden. Es können neben Zahlen auch Labels aus dem Code eingefügt werden.
.dw 0x0000, 0x0100,0x0200, 0x0300 ;Definition einer Zahlenfolge aus 16-Bit Werten
.dw Reset, Loop, Taste, KeineTaste ; Definition einer Folge aus Sprungadressen durch Labels