Einsatzmöglichkeiten der vielen Rechen-Register von AVR-Microcontrollern

Seitenübersicht



 www.schramm-software.de

Die AVR-Microcontroller verfügen über die stattliche Zahl von 32 universell verwendbaren 8bit-Registern, bezeichnet von R0 bis R31. Programmiert man in Assembler, hat man die volle Kontrolle über den Registereinsatz und sollte diesen besonders einfach und schnell ansprechbaren Speicherbereich ausgiebig nutzen. In kleineren Anwendungen reichen die Register möglicherweise zur Datenspeicherung komplett aus, so dass man - außer im Zusammenhang mit Unterprogrammaufrufen und Interrupt-Routinen - unter Umständen ganz auf die Nutzung des SRAMs verzichten kann.

Unterschiedliche Wertigkeit der Register

Die Register sind nicht völlig gleichwertig. Die Register der oberen Hälfte (R16 - R31) sind 'wertvoller', da nur für sie Kommandos mit Direktwerten existieren, z. B.:

 ldi r16,100 ; lade die Zahl 100 in das Register R16
 andi r20,7 ; Und-Verknüpfung mit 7, also die unteren drei Bits in R20 isolieren

Darüber hinaus besitzen die Register 26 bis 31 einen Sonderstatus; sie können paarweise zu 16bit-Registern zusammengefasst werden, die als Adresspointer einsetzbar sind und - in Grenzen - eine 16bit-Arithmetik erlauben. Soll ein Programm Multiplikationsbefehle verwenden (nur bei den 'größeren' Controllertypen möglich), sollte man zudem das Registerpaar R0:R1 freihalten, da dieses das Rechenergebnis aufnimmt.

Kurzum: Man sollte geschickt planen, welches Register man für welchen Zweck verwendet, um kein zu 'wertvolles' Register für einen schlichten Zweck zu verschwenden. Verwendet man systematisch symbolische Namen für die Register, ist eine Änderung der Zuordnung jedoch jederzeit mit geringem Aufwand möglich.

Symbolische Namen für globale Variablen

Register, die über einen größeren Programmbereich hinweg als Speicher für eine bestimmte Aufgabe eingesetzt werden, sollten mit einem symbolischen Namen versehen und nur über diesen angesprochen werden. Das verbessert die Lesbarkeit des Programms und vermindert die Gefahr, versehentlich noch benötigte Registerinhalte zu überschreiben. Es kann sich sogar lohnen, Register für häufig benötigte Zahlenwerte zu 'opfern', soll heißen, zu Anfang des Programms die Register zu füllen und ab dann nur noch lesend darauf zuzugreifen. Ein Beispiel:

; Registerdefinitionen vor dem eigentlichen Programm:
.DEF einsreg = r13 ;konstant 1
.DEF nullreg = r14 ;konstant 0
.DEF intreg  = r15 ;nur als Zwischenspeicher in Interrupt-Routinen
.DEF flags   = r24 ;diverse Schalter, folgende Bedeutung: ...
...
; Initialisierungsphase zu Anfang des Programms:
...
 clr einsreg
 inc einsreg ;einsreg (R13) bleibt dauerhaft 1
 clr nullreg ;nullreg (R14) bleibt dauerhaft null
 clr flags
...
; Nutzung der Register:
 out PORTB,einsreg ;Pull-Up-Widerstand an PB0 aktivieren
 sbr flags,(1<<7)+(1<<4) ;Schalter ... und ... setzen
...

Registerverwendung in Interruptroutinen

Eine besondere Rolle wurde in diesem Beispiel dem Register 13 mit dem symbolischen Namen intreg zugewiesen. Es soll nur in Interruptroutinen zur (meist zwingend notwendigen) Rettung des Statusregisters verwendet werden. Wiederum ein Anwendungsbeispiel:

i_t0ov: ; *** Timer/Counter Overflow
  in intreg,sreg ;Statusregister merken
...
  out sreg,intreg ;Statusregister wiederherstellen
reti ;Interrupt-Routine beenden

Die Adresse i_t0ov muss selbstverständlich in der Interrupttabelle eingetragen sein. Gegenüber der Standardmethode, das Statusregister auf dem Stack zwischenzuspeichern, spart die Bereitstellung eines Rechenregisters ein paar Taktzyklen, die in zeitkritischen Anwendungen wertvoll sein können. Eventuell können mit derselben Zielsetzung weitere Register zur ausschließlichen Verwendung in Interruptroutinen reserviert werden. Der Nachteil dieser Vorgehensweise besteht natürlich darin, dass eine Inhaltsänderung dieser Register im Hauptprogramm tabu ist und dass von mehreren I-Routinen, die sich gegenseitig unterbrechen dürfen, nur eine die Registerinhalte ändern darf.


Mehr Informationen zum Thema?

So viel zum Thema Register! Das ist ein kleiner Ausschnitt dessen, was über die Assemblerprogrammierung zu lernen wäre. Wer mehr erfahren möchte, sollte auf die vielen Tutorials zurückgreifen, die sich im Internet finden lassen. Eine Suche z. B. nach "avr assembler tutorial" bringt bestimmt weiter!

Wer's lieber in gedruckter und gebundener Form mag und bereit ist, ein paar Euro auszugeben, findet auch Bücher über die Assemblerprogrammierung - etwa bei Amazon.

Oder, wie schon an anderer Stelle geschrieben, einfach mal bei buecherbillig.de hereinschauen und nach Sonderangeboten Ausschau halten.


Zurück zur Übersicht