Forum: Mikrocontroller und Digitale Elektronik Wie & wo Register sinnvoll definieren?


von AndyW (Gast)


Lesenswert?

Hallo zusammen,

ich habe ein größeres Programm, wo ich die Register auf Grund
der begrenzten Anzahl mehrfach definieren muß.

Dies geschieht lokal in der entsprechenden Datei mit .def und .undef


z.B. in "bus.asm"

.def byte_counter = r10

/*Funktion 1*/
...

/*Funktion 2*/
...

.undef byte_counter



in "telegrams.asm"

.def telegram_counter = r10

/*Funktion 1*/
...

/*Funktion 2*/
...

.undef telegram_counter


Die Dateien sind alle in der Main.asm includiert. Somit bekomme ich 
keine Warnings beim Kompilieren wegen Doppeldefinitionen von Registern.

ABER:

Wenn ein Register durch die Doppelbelegung in einer Unterfunktion 
überschrieben wird, führt dies natürlich zu Fehlern im Programm. 
Außerdem werden diese Variablen beim Debuggen im AVR-Studio nicht 
angezeigt ("Not in Scope")

Gibt es bezüglich der Definitionen eine elegantere/sinnvollere 
Möglichkeit oder wie löst Ihr das?

Danke im Voraus!

Andy

von Uwe (Gast)


Lesenswert?

Hi!
Warum musst du denn die Register mehrfach definieren?
Kannst du nicht einfach byte_counter und telegram_counter nur als 
counter
definieren? Ich halte das für deutlich übersichtlicher, vorallem merkst 
du wenn du anfängst DAS Register zu überschreiben.
<Wenn ein Register durch die Doppelbelegung in einer Unterfunktion
<überschrieben wird, führt dies natürlich zu Fehlern im Programm.
Das ist immer die Aufgabe des Schreiberlings solche Sachen zu beachten. 
Mehrfachdefs helfen da natürlich ungemein.

MFG Uwe

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Also ich würde mal deine Funktionen optimieren!
Ich hab meistens zwei temp register (r16 und r17) und dann eins für die 
Flags.

ggf dann noch ein paar globale counter.
Funktionen pushen dann benötigte Register auf den Stack und restaurieren 
sie danach wieder (auch das SREG) auf die weise kommt man mit 32 
register eigetlich endlos lange hin!

von 42 (Gast)


Lesenswert?

Lokale Variablen (Register) beschafft man sich temporär über den Stack 
(SRAM vorausgesetzt), indem man den Inhalt der zu benutzenden Register 
sichert und wiederherstellt (Push/Pop).

Hat der Controller keinen SRAM (z.B. einige ATtinys), dann nimmt man 
einige Register exklusiv nur für ISRs, einige andere nur für UPs. Da die 
Verschachtelungstiefe aufgrund des Hardwarestacks eh nur gering ist, 
kann man damit zurecht kommen. Reichen die Register trotzdem nicht, dann 
ist entweder das Programmkonzept falsch, oder der Controller zu klein.

MFG

von AndyW (Gast)


Lesenswert?

Hallo,

Danke für die schnellen Antworten!

@Uwe

>Warum musst du denn die Register mehrfach definieren?

Um meinen Code (für mich) lesbarer zu gestalten. Gerade wenn ich nach 
längerer Zeit wieder an einem Programmteil arbeite, erleichtert es mir 
den "Wiedereinstieg" ungemein. Das Beispiel mit meinen Countern ist 
vielleicht etwas ungünstig gewählt, die könnten auch eine ganz andere 
Fkt haben.

@Läubi
@42

Ok- die Register pushen ist dann wohl die Lösung. Macht Ihr das 
konsequent in jeder Funktion? (Sei sie auch noch so klein und nutzt nur 
wenige Variablen)


MFG
Andy

von 42 (Gast)


Lesenswert?

> Ok- die Register pushen ist dann wohl die Lösung. Macht Ihr das
> konsequent in jeder Funktion? (Sei sie auch noch so klein und nutzt nur
> wenige Variablen)

Das mag jetzt Haarspalterei sein, aber ich rufe (in ASM) keine 
Funktionen auf. Ein Funktionsaufruf hat eine Parameterliste, der Aufruf 
eines Unterprogramms nicht. ;-)

Meine Unterprogramme nutzen Exklusivregister, solange noch genügend 
Register frei sind. Wird es enger, so wird erstmal überlegt, welche 
Variablen nicht allzuoft geändert werden und diese ins SRAM ausgelagert. 
Ist es danach immer noch eng mit den Registern, dann werden die in den 
Unterprogrammen benötigten Register auf Stack gesichert.

Ähnlich ist es mit den ISRs. Wird die ISR häufig aufgerufen (schneller 
Timer, Ext.-Int), dann bekommt sie Exklusivregister. Wird sie eher 
selten aufgerufen (z.B. Timer mit mehr als 300 Takten bis zum 
Interrupt), dann können die Variablen vom Stack besorgt werden. Alle 
ISRs können (beim AVR und ohne SEI in der ISR) die gleichen lokalen 
(temporären) Variablen benutzen.

MFG

von AndyW (Gast)


Lesenswert?

Danke, ich glaube jetzt habe ich die Richtung!

MFG
Andy

von Michael U. (Gast)


Lesenswert?

Hallo,

hilfreich ist es manchmal auch, wenn man den logischen Programmablauf im 
Hinterkopf hat. Oft können bestimmte Dinge können nie gleichzeitig 
gültige Werte in den registern haben.
Als Beispiel: meine Software für einen Tuner mit RDS braucht mehrere 
Register für die PLL-Steuerung und auch für den RDS-Dekoder.
PLL ist nur nötig, wenn der Sender gewechselt wird, die Daten dazu kann 
ich also im Ram halten und bei Bedarf laden.
Dazu kann ich die eigentlich für RDS reservierten Register nehmen, weil 
nach einem Senderwechsel diese Daten mit Sicherheit ungültig sind (die 
stammen ja noch vom alten Sender) und der Dekoder die komplett neu 
füllen muß.

Ein Kommentar bei den Register-Definitionen erinnert mich an diesen 
Umstand auch später noch.

Ansonsten halte ich es ähnlich wie Läubi, 2-4 Temp-Register und 1-2 
Flagregister.
Seltene Sachen liegen im Ram und werden im Unterprogramm in die TEMP 
geholt und hinterher wieder ins Ram gelegt.
Reichen die Temp mal nicht, wird irgendwas mit Push/Pop gesichert.
Parameter reiche ich oft per Temp-Register oder Zeiger in Y oder Z an 
ein Unterprogramm, in ISR wird generell alles gesichert, was angefasst 
wird.

Gruß aus Berlin
Michael

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.