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
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
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!
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
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
> 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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.