Forum: Compiler & IDEs Register sichern vor main


von Benedikt K. (benedikt)


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.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

__attribute__((OS_main))

von Peter D. (peda)


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

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


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.

von Peter D. (peda)


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

von Peter D. (peda)


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

von Rolf Magnus (Gast)


Lesenswert?

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

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


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. ;-)

von Benedikt K. (benedikt)


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

von Maximilian K. (laplace)


Lesenswert?

Schonmal

int __attribute__(OS_main) main(void);

probiert?

von Benedikt K. (benedikt)


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

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Benedikt K. wrote:

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

Please upgrade.

von Benedikt K. (benedikt)


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 ?

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


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):
1
-Wl,--defsym=__floatunsisf=__floatunssisf -Wl,--defsym=__floatundisf=__floatunsdisf

von Klaus W. (Firma: privat) (texmex)


Lesenswert?

Jörg Wunsch schrieb:
> __attribute__((OS_main))

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


Viele Grüße,
Klaus

von Axel H. (axelh)


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

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.