www.mikrocontroller.net

Forum: Compiler & IDEs For-Loop wird nicht richtig ausgeführt


Autor: Sepp (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo
Habe ein Problem,wenn ich eine einfaches C-Programm im AVR Studio 4.12 
neustes update mit GCC Unterstützung simulieren will. (Habe schon in 
Assembler programmiert jedoch wenig in anderen C-Compiler)

Umgebung: windows xp, Atmel stk 500, Atiny 13

Beispiel: For loop

int an;
....
 for(an=0;an<=10;an=an+1)
.....

da sollte doch "an" um eins hochgezählt werden bis 10.
 Aber im Debugger ist die Variable beim ersten For-Schritt schon bei 11 
(elf!) (auch Im Watch Fenster) angelangt und die Schleife wird natürlich 
sofort verlassen!
Habe andere Variablen probiert wie auch z.B. andere Start und Endwerte 
verwendet.
Kann mir das nicht vorstellen

Danke für einen Hinweis
Viele Grüsse

Autor: Erwin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das hört sich so an, als wenn die For-Schleife leer ist. Poste doch mal 
den gesamten Code.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Compiler hat gewisse Freiheiten, unsinnigen Code rauszuwerfen. Nennt 
sich Optimierung. Eine leere for-loop mit einer normalen Variablen ist 
sowas.

Wenn du Wert drauf legst, dass jeder scheinbare Unsinn mit einer 
Variablen drin bleibt, dann mach sie volatile.

Autor: Andreas B. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kommt drauf an, was in der Schleife steht. GCC kann da auch eine ganze 
Schleife wegoptimieren wenn es den Schleifeninhalt auch ohne Schleife in 
einem Rutsch ausführen kann.

Mal als Beispiel:
unsigned int test(unsigned int n)
{
  unsigned int x;

  for (x = n; x < n + 20; x++)
    ;

  return x;
}

Mit eingeschalteter Optimierung (-O2) wird das auf x86 zu:
0000000000000000 <test>:
   0:  89 f8                  mov    %edi,%eax
   2:  83 c0 14               add    $0x14,%eax
   5:  0f 42 c7               cmovb  %edi,%eax
   8:  c3                     retq   

Man sieht, da wird anstatt 20 mal zu inkrementieren direkt 20 addiert.


Wenn du alles wie im Quellcode ausgeführt sehen willst, musst du die 
Optimierungen ausschalten. Mit Optimierungen wird es auch auf andere 
Weise unübersichtlich im Debugger, z.B. kann die Reihenfolge der 
Anweisungen umgestellt werden.

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hier mal ein kleines Beispielprogramm:
int fac (int x)
{
    if (x == 0)
        return 1;

    return x * fac (x-1);
}

int main()
{
    return fac (7);
}

avr-gcc 4.5.1 bzw. 4.6.0 mit -O2 macht aus main:
main:
  ldi r24,lo8(5040)
  ldi r25,hi8(5040)
  ret

d.h. der (end-)rekursive Aufruf ist komplett verschwunden. Es wird nur 
7! ins return-reg geladen. Da die Fakultätsfunktion hier nicht-statisch 
ist, muss sie ausimplementiert werden. Das sieht für einen ATmega8 und 
auf Größe optimiert so aus:
fac:
  ldi r18,lo8(1)
  ldi r19,hi8(1)
.L3:
  sbiw r24,0
  breq .L2
  movw r20,r18
  mul r20,r24
  movw r18,r0
  mul r20,r25
  add r19,r0
  mul r21,r24
  add r19,r0
  clr r1
  sbiw r24,1
  rjmp .L3
.L2:
  movw r24,r18
  ret

Nix mehr mit Rekursion. gcc erzeugt eine normale Schleife.

Ergo: Der Compiler transformiert den Code so, daß er die gleiche Wirkung 
hat, aber kann das auf ganz anderen Wegen erreichen, als man anhand der 
Quelle zu glauben geneigt ist. Entsprechend verwirrend kann das Debuggen 
solchen Codes ausfallen.

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.