www.mikrocontroller.net

Forum: Compiler & IDEs Rechen-Zuweisung von Variable in GCC


Autor: G. B. (garyb)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

irgendwie stehe ich auf dem Schlauch - geb gerne zu das mein C 
eingerostet ist, aber warum der WINAVR-GCC die folgende Zeile nicht
ausführt bzw. anscheinend erst gar nicht compiliert - verstehe ich nicht


  TimerCnt += 32/8; //_TIME_CONST_US_TIMER_CLOCK (32); //

Diese Zeile erscheint in keinster Weise im Disassembler-Code.
Beim Debuggen hüpft er drüber und die Variable hat den Wert Null.
Compiler-Option -Os (keine Optimierung ) ist gewählt.

Mache ich daraus ein

             TimerCnt += 4;

dann wird die Zeile ausgeführt....
Kann mir jemand auf die Sprünge helfen was die schief geht?
Gruss,
Gary

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
In deinem Code steht

TimerCnt += 32.0/8.0;

Das ist ein Ausdruck vom Typ "float", schreibt mal (wie oben)

TimerCnt += 32/8; /* Integer-Ausdruck */

Vielleicht klappts dann.

Autor: G. B. (garyb)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sorry das war der letzte Spielstand, aber es ging in jedem Fall nicht.

Autor: G. B. (garyb)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Da läuft irgendwas im Compiler schief

habe nun ein noch einfachers Beispiel gezimmert...

anbei das Disassembly
@00000030: main
12:       {
+00000030:   E084        LDI     R24,0x04         Load immediate
+00000031:   E090        LDI     R25,0x00         Load immediate
+00000032:   019C        MOVW    R18,R24          Copy register pair
7:          while(--i);
+00000033:   01C9        MOVW    R24,R18          Copy register pair
+00000034:   9701        SBIW    R24,0x01         Subtract immediate 
from word
+00000035:   E024        LDI     R18,0x04         Load immediate
+00000036:   E030        LDI     R19,0x00         Load immediate
+00000037:   F7D1        BRNE    PC-0x05          Branch if not equal
+00000038:   CFFA        RJMP    PC-0x0005        Relative jump
+00000039:   94F8        CLI                      Global Interrupt 
Disable
+0000003A:   CFFF        RJMP    PC-0x0000        Relative jump

Autor: Εrnst B✶ (ernst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ist doch alles richtig?

die Delay-Methode wird inline in main reinkopiert, die Berechnungen auf 
Var werden wegoptimiert, weil der berechnete Wert nie verwendet wird.

Autor: G. B. (garyb)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ernst
Das der Compiler hier optimiert habe ich mir auch schon überlegt,
aber deswegen habe ich auch die Option -Os drin gelassen.

hier ein erweitertes Beispiel
#include <stdio.h>
#include <stdint.h>

void Delay( void )
{
  uint16_t i=  0x4;/*1 7FFF;*/
  while(--i);
}


int main(void)
{
  uint8_t Var=0;
  uint8_t Test;

  while ( 1 )
  {
    Delay();
   // Var = 32/8;
      Var = Var+1;
    Test = Var;
    for (Test = 0; Test<= Var; Test++) { }
  }
}

So gehts - nimm die kommentierte Zeile wieder rein - und er macht nichts 
auser dem Delay.

Autor: Εrnst B✶ (ernst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dann optimiert dein GCC schlecht.
Bei mir kommt raus:
Version mit "Var=32/8":
.L10:
        ldi r24,lo8(4)
        ldi r25,hi8(4)
.L9:
        sbiw r24,1
        brne .L9
        rjmp .L10

Version ohne:
        ldi r18,lo8(0)
.L4:
        subi r18,lo8(-(1))
        ldi r24,lo8(0)
        ldi r25,hi8(0)
.L5:
        adiw r24,1
        cp r18,r24
        brsh .L5
        rjmp .L4


Tip:
uint16_t i=  0x4;
  while(--i);
kann der Compiler optimieren zu:
uint16_t i=0;
und wenn i nicht weiter verwendet wird, kann er es ganz rausschmeissen.

Ähnlich:
 for (Test = 0; Test<= Var; Test++) { }
Wird zu:
  Test=Var+1;

Autor: G. B. (garyb)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ernst...

danke... habe mir nun die brand-aktuelle Version geladen UND
habe gerade festgestellt das -Os ja doch auf Size optimiert.
Mit der Option -O0 ist gut, dann macht er alles richtig...
sorry für die Mühe, aber manchmal ;)
Ich wollte ja nur mein Makro testen ;))

Danke nochmal

Autor: Εrnst B✶ (ernst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gerhard Brünner wrote:
> @ernst...
>
> danke... habe mir nun die brand-aktuelle Version geladen UND
> habe gerade festgestellt das -Os ja doch auf Size optimiert.
> Mit der Option -O0 ist gut, dann macht er alles richtig...
>
Richtig macht er es auch mit -Os, zumindest was das Ergebnis anbelangt.

Aber zum ASM-Code anschauen ist -O0 besser geeignet, oder halt auf 
einzelnen Variablen das Optimieren verbieten, mit "volatile"...

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.