Für AVR-GCC ist main eine normale Funktion wie jede andere, daher werden zunächst alle Register gesichert. In nahezu allen Fällen ist das aber unnötig, da nach main meist nichts mehr kommt. So werden locker mal >16Byte RAM verschwendet, die vor allem bei kleineren tinys gut zu gebrauchen wären. Kann man den Compiler irgendwie dazu bringen, in der main Funktion keine Register zu sichern ? _attribute_ ((naked)) habe ich schon probiert, aber dann wird eben garnichts gemacht, nichtmal Speicherplatz für lokale Variablen auf dem Stack geschaffen.
Benedikt K. wrote: > Für AVR-GCC ist main eine normale Funktion wie jede andere, daher werden > zunächst alle Register gesichert. ??? Also ich kann nirgends ein Push im Startup-Code entdecken, bevor das Main aufgerufen wird (GCC4.2.2). Rufst Du das Main rekursiv auf oder fehlt vielleicht die Mainloop? Peter
Peter Dannegger wrote: > Also ich kann nirgends ein Push im Startup-Code entdecken, bevor das > Main aufgerufen wird (GCC4.2.2). Der startup-Code hat mit der Compilerversion absolut gar nichts zu tun -- der kommt aus der Bibliothek. Aber das ist gar nicht das Thema, sondern vielmehr dass der Compiler in der Funktion main() selbst all die Register rettet, die er gemäß ABI retten muss. main() ist eben gemäß C-Standard erst einmal eine Funktion, die kann sich theoretisch auch rekursiv selbst aufrufen.
Danke, jetzt ist mir klar, was gemeint ist. Ich hab allerdings kaum lokale Variablen im Main, so daß der Effekt bei mir nicht auftritt. Das Main ist bei mir hauptsächlich nur eine Schleife, die Unterfunktionen aufruft. Bzw. die auszuwertenden Variablen sind global (z.B.Timer, die ablaufen usw.). Peter
Jörg Wunsch wrote: > main() ist eben gemäß C-Standard erst einmal eine > Funktion, die kann sich theoretisch auch rekursiv selbst aufrufen. Das funktioniert sogar. Ältere AVR-GCC hatten aber im Main den Stack nochmal neu initialisiert, da gings noch nicht. Peter
Das ist übrigens nur in C so. In C++ ist der Aufruf von main() explizit verboten.
Rolf Magnus wrote: > Das ist übrigens nur in C so. In C++ ist der Aufruf von main() explizit > verboten. Das wird die Leute vom Obfuscated C++ Contest aber ärgern. ;-)
Jörg Wunsch wrote:
> __attribute__((OS_main))
Funktioniert leider nicht:
int main(void) __attribute__((OS_main));
int main(void)
{....}
main.c:21: warning: 'OS_main' attribute directive ignored
Geht noch weniger: main.c:21: error: expected '(' before 'OS_main' int __attribute__((OS_main)) main(void); ist besser, aber es bewirkt auch nichts: main.c:21: warning: 'OS_main' attribute directive ignored
Benedikt K. wrote:
> main.c:21: warning: 'OS_main' attribute directive ignored
Please upgrade.
Das geht also nur bei der neuesten Version ? Schade, dann muss ich wohl bei Assembler bleiben, oder wurde mittlerweile der Bug mit dem hohen RAM Verbrauch float behoben ?
Benedikt K. wrote: > Das geht also nur bei der neuesten Version ? Ja, erst dort ist der Patch drin. > Schade, dann muss ich wohl > bei Assembler bleiben, oder wurde mittlerweile der Bug mit dem hohen RAM > Verbrauch float behoben ? Du machst float in Assembler? Herzlichen Glückwunsch! Der Bug ist in der avr-libc selbst behoben. Das war letztlich nur ein Namensproblem, GCC 4.2 hat hier interne Namen geändert, auf die sich die avr-libc verlassen hat. Einen neuen avr-libc-1.6.x-Release wird es im Februar geben. Ohne Pistole oder Gewehr, das müsste sich eigentlich durch folgende Compileroptionen beim Linken beheben lassen (bis zur neuen Version):
1 | -Wl,--defsym=__floatunsisf=__floatunssisf -Wl,--defsym=__floatundisf=__floatunsdisf |
Jörg Wunsch schrieb:
> __attribute__((OS_main))
Hm, aber irgendwo auf gcc.gnu.org dokumentiert ist das nicht, oder?
Viele Grüße,
Klaus
Es gibt noch das Attribut "noreturn", mit dem du dem Compiler sagst, dass die Funktion nicht zurückkehren wird - und er deswegen auch keine Register sicher muss. Du du musst dann nur dafür sorgen, dass deine main() Funktion auch nicht zurück kehrt, sie also z.B. in einer Endlosschleife bleibt. Sonst schmeisst der Compiler eine Warnung aus. Axel
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.