Forum: Compiler & IDEs Welche Ausdrücke werden wann ausgewertet?


von Christian W. (clupus)


Lesenswert?

Hallo,

nur eine kurze Frage zur Auswertung von Ausdrücken in AVR-GCC:
Wenn ich nun z.B. folgenden Ausdrück auswerten lasse:

» PORTA |= _BV(PORTA1) | _BV(PORTA2);

Sollte mein Pin A1 und A2 auf hi gehen (Wenn als Ausgang eingestellt).
Intern muss GCC ja im Assember etwas in der Art erzeugen (sorry, falls
da etwas nicht simmen sollte; hab schon seit einigen Jahren nicht mehr
in Assembler geschrieben, v.a. keine AVRs):

» in R1,PORTA
» ori R1,#0b00000110
» out PORTA,R1

Aber woher weiß ich, dass er nicht auch die Erstellung des Binärwertes
den AVr rechnen lässt? Ich meine, das ist doch zwar ne Konstante, die
aber nur ein einziges Mal im Programm gebraucht wird (v.a. wenn
irgendwelche Einstellungen in irgendwelchen Sonder-Registern gemacht
werden müssen!). Kann ich ihm sagen: Rechne das selber aus und gib dem
AVR nur eine Konstante weiter oder macht der das bei Optimierung
automatisch?

MfG
Christian

von Ulrich (Gast)


Lesenswert?

Bei den Ports usw. optimiert der compiler nichts da die ganzen prozessor
register mit volatile gekennzeichnet sind...

von Christian W. (clupus)


Lesenswert?

Aber die Frage ist: Macht er daraus
» ori R1,0b00000110

oder macht er daraus
» ldi R2,0b00000010
» ldi R3,0b00000100
» ori R2,R3
» ori R1,R2

Das sind dann doch ein paar Zyklen mehr. Und wenn das dann in 'ner
Schleife häufig abgearbeitet wird, wird ziemlich viel "Müll"
gerechnet.

MfG
Christian

von Karl H. (kbuchegg)


Lesenswert?

> optimiert der compiler nichts da die ganzen prozessor
> register mit volatile gekennzeichnet sind

Das volatile hat damit überhaupt nichts zu tun.

Worum es hier geht ist eine Optimierung, die generell
als 'Constant Folding' bezeichnet wird. Compiler machen das
seit über 30 Jahren. Ist nicht schwierig zu implementieren
und ein Compiler der das nicht beherrscht, hat auf dem Markt
keine Chance. Egal ob Freeware oder kommerziell.

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


Lesenswert?

> ein Compiler der das nicht beherrscht, hat auf dem Markt
> keine Chance.

Oh, sag das nicht.  Als ich mich mal kurz mit PICs beschäftigt
habe (was mich dann zu den AVRs gebracht hat :), hab' ich mir
mal JAL angesehen ("Just another language").  Der Mann hat ja
nette Ideen gehabt wie Bit-Variablen, aber als ich dann
gesehen habe, dass der arme PIC selbst die zur Compile-Zeit
bekannten Konstanten alle selbst ausrechnen musste, hab' ich
ganz schnell die Finger davon gelassen...

von Christian Wolf (Gast)


Lesenswert?

Wann machen die das und wann nicht? Gibt's da irgendweöche Regeln (zum
groben einordnen) oder muss ich da disassembeln?

MfG
Christian

von A.K. (Gast)


Lesenswert?

Operationen mit Konstanten sind der einfachere Fall. So wird jeder
ernsthafte Compiler "2 * 10" zu "20" zusammenfassen.

Komplizierter liegt der Fall, wenn keine der Operationen selbst
konstant ist, bespielsweise bei "2  x  10". Da kann ein Blick in
den generierten Code erforderlich sein.

Manche Compiler könnten auch "x  2  10" als "(x * 2) * 10"
interpretieren und mindestens bei abgeschalteter Optimierung exakt so
ausführen. In solchen Fällen können Klammern ihm auf die Sprünge
helfen.

Feste Regeln gibt es keine.

von johnny.m (Gast)


Lesenswert?

Rein informativ:
> ori R1,#0b00000110
Die immediate-Operatoren ori, andi usw. gehen nur mit r16..r31

> ori R2,R3
...und das muss wenn überhaupt "or r2, r3" heißen.

Wenn Du Dir übrigens beim Compilieren eine List-Datei (*.lss) erzeugen
lässt, dann kannst Du i.d.R. genau nachvollziehen, welcher C-Code in
welchen Assembler-Code übersetzt wird.

von Karl heinz B. (kbucheg)


Lesenswert?

> Compile-Zeit bekannten Konstanten alle selbst ausrechnen musste,
> hab' ich ganz schnell die Finger davon gelassen...

:-)
Sag ich doch: keine Chance.

von Christian Wolf (Gast)


Lesenswert?

Wie kann ich so eine .lss Datei erzwugen? (welche Parameter muss ich
welchem Programm übergeben?)
Ist es sinnvoll noch weitere Dateien zu erzeugen? Momentan lasse ich
ihn aus der C eine .o-Datei machen (mit avr-gcc -c $(PGM).c [...]-o
$(PGM).o) und die dann in eine .out-Datei umsetzen (avr-gcc -g -o
$(PGM).out $(PGM).o [...]). Dann wird da die hex-File draus
herausgenommmen und fertig, oder ist da sonst noch was sinnvoll
(map-file, lss-file, ...)? Wie ist das jeweils zu machen?

MfG
Christian

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.