www.mikrocontroller.net

Forum: Compiler & IDEs Register sichern vor main


Autor: Benedikt K. (benedikt) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
__attribute__((OS_main))

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das ist übrigens nur in C so. In C++ ist der Aufruf von main() explizit 
verboten.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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. ;-)

Autor: Benedikt K. (benedikt) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Maximilian K. (laplace)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Schonmal

int __attribute__(OS_main) main(void);

probiert?

Autor: Benedikt K. (benedikt) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Benedikt K. wrote:

> main.c:21: warning: 'OS_main' attribute directive ignored

Please upgrade.

Autor: Benedikt K. (benedikt) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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 ?

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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):
-Wl,--defsym=__floatunsisf=__floatunssisf -Wl,--defsym=__floatundisf=__floatunsdisf

Autor: Klaus W. (Firma: privat) (texmex)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jörg Wunsch schrieb:
> __attribute__((OS_main))

Hm, aber irgendwo auf gcc.gnu.org dokumentiert ist das nicht, oder?


Viele Grüße,
Klaus

Autor: Axel H. (axelh)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.