Rechen-Zuweisung von Variable in GCC

OP #916333
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
Angehängte Dateien:
OP #916350
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
Angehängte Dateien:
OP #916369
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.
#916375
Lesenswert?

Dann optimiert dein GCC schlecht.
Bei mir kommt raus:
Version mit "Var=32/8":
1
.L10:
2
        ldi r24,lo8(4)
3
        ldi r25,hi8(4)
4
.L9:
5
        sbiw r24,1
6
        brne .L9
7
        rjmp .L10

Version ohne:
1
        ldi r18,lo8(0)
2
.L4:
3
        subi r18,lo8(-(1))
4
        ldi r24,lo8(0)
5
        ldi r25,hi8(0)
6
.L5:
7
        adiw r24,1
8
        cp r18,r24
9
        brsh .L5
10
        rjmp .L4


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

Ähnlich:
1
 for (Test = 0; Test<= Var; Test++) { }
Wird zu:
1
  Test=Var+1;
OP #916378
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
#916385
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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren