www.mikrocontroller.net

Forum: Compiler & IDEs mega 32 compilerfehler


Autor: M. Gerlach (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hallo leute

ich hatte im laufe der woche schon eine umfrage gestartet wegen eines
vermuteten compilerfehlers. hier nochmal die eckdaten:

avrgcc3.3, pn2, avrstudio4.11 und jtag-ice
compilereinstellungen: richtiger controller, optimierung s
programmiert wird in c.

folgendes detail:

123:        dac_set_value(URDM_1,-1.5);    // AP für MOSFET UGS=-3V
+00000FC2:   E040        LDI     R20,0x00         Load immediate
+00000FC3:   E050        LDI     R21,0x00         Load immediate
+00000FC4:   EC60        LDI     R22,0xC0         Load immediate
+00000FC5:   EB7F        LDI     R23,0xBF         Load immediate
+00000FC6:   E081        LDI     R24,0x01         Load immediate
123:        dac_set_value(URDM_1,-1.5);    // AP für MOSFET UGS=-3V
+00000FC7:   940E0000    CALL    0x00000000       Call subroutine
127:          dac_set_value(US_1,1.5);    // Startpunkte setzen
+00000FC9:   E040        LDI     R20,0x00         Load immediate
---- No Source
------------------------------------------------------------------------ 
------------
+00000FCA:   E050        LDI     R21,0x00         Load immediate
+00000FCB:   EC60        LDI     R22,0xC0         Load immediate
+00000FCC:   E37F        LDI     R23,0x3F         Load immediate
+00000FCD:   E080        LDI     R24,0x00         Load immediate
+00000FCE:   CFF8        RJMP    PC-0x0007        Relative jump

hinter diesem asm-code verbergen sich folgende zeilen im pn

  dac_set_value(URDM_1,-1.5);

  for(;;)
  {
    dac_set_value(US_1,1.5);

  }
effekt1:

der pc wird vom compiler aus der schleife herausgeschickt
in die zeile vor der schleife!

+00000FCE:   CFF8        RJMP    PC-0x0007        Relative jump

wer hat infos woran das liegen kann?

m. gerlach

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gib mal bitte ein Stückchen minimalen C-Code, der das
reproduziert, statt eines Schnipsels aus dem Disassembler
von AVR Studio (der noch dazu bekanntermaßen mit negativen
Offsets Probleme hat).

Autor: M. Gerlach (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
der c-code sieht so aus


 dac_set_value(URDM_1,-1.5);

  for(;;)
  {
    dac_set_value(US_1,1.5);

  }
die funktion ist jedoch etwas umfangreicher

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Naja, ich wollte etwas compilierfähiges haben, damit ich mir
den Compiler-Output mal angucken kann.

Aber eigentlich hat sich das schon erledigt, mir ist auf dem
Heimweg beim Radeln eingefallen, dass der Compiler eben einfach
nur genial compiliert hat.

Der Code ist komplett korrekt.  Der Compiler hat nur festgestellt,
dass er die beiden Funktionsaufrufe in einen vereinigen kann.
Das ist ein typisches Beispiel, an dem man sieht, dass es eben
einfach nicht immer eine 1:1-Zuordnung vom Objektcode zurück zum
C-Code geben kann: der Funktionsaufruf auf Adresse 0xFC7 gehört
sowohl zu Zeile 123 als auch Zeile 127 im Quelltext.

Autor: A.K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wo ist nun dein Problem? Der RJMP spring nach 0FC7 und genau das soll er
doch auch. Nur ist der Compiler ein bischen schlauer als Du angenommen
hast, denn er verwendet den selben CALL-Befehl gleich für beide
Funktionsaufrufe. Nur eben mit verschiedenen Parametern. Genau wie er
soll.

Autor: Marco Gerlach (macro)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Jörg


Ja und was soll ich jetzt tun damit dieser Fehler nicht mehr auftritt?
Denn es ist doch wohl ein Fehler. Oder?

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nein.  Den Fehler gibt's nur in deinem Kopf.  Du hast der
Schrittverfolgung im Debugger (die dich ja nur auf der
Ebene von C-Codezeilen arbeiten lässt) mehr vertraut als
der realen Funktion des generierten Codes.

Autor: Unbekannter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wieso? Es stimmt doch alles.

Ausserhalb und innerhalb der Schleife wird doch die gleiche Funktion
aufgerufen. Also passiert bei Ablauf des Codes folgendes:

  1.) Werte für den ersten Funktionsausruf laden.
  2.) Funktion aufrufen.
  3.) Werte für den Funktionsaufruf in der Endlosschleife laden.
  4.) Goto zu Schritt 2.

Alternativ könntest Du das natürlich auch so schreiben:

  1.) Werte für den ersten Funktionsausruf laden.
  2.) Funktion aufrufen.
  3.) Werte für den Funktionsaufruf in der Endlosschleife laden.
  4.) Funktion aufrufen.
  5.) Goto zu Schritt 3.

Das nun hat aber einen unnötigen Schritt zuviel. Also kann man den auch
wegoptimieren...

Und noch lustiger wird es beim gcc-4.x mit Tail-Call-Optimierungen,
besonders in rekursiven Funktionen.
Da kann man dann in C fast schon so wie in LISP programmieren, und
trotzdem gibt's kein Stack-Overflow. ;-)

Autor: Marco Gerlach (macro)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
OK das leuchtet mir soweit sogar ein. Aber die funktionen werden auch
sozusagen vertauscht ausgeführt.
ich habe einen haltepunkt in die endlosschleife gesetzt. springt der
debugger da hin und lasse ich den nächsten schritt ausführen springt
der debugger aus der schleife führt dabei aber nicht die funktion in
der schleife aus. erst wenn der debugger wieder über die "aussere"
funktion gelaufen ist passiert hardwaremässig das was passieren soll.

und warum ist das kein fehler wenn ich will, dass die "aussere"
funktion nur einmal ausgeführt wird jedoch die "innere" im anschluss
daran ständig und er faktisch beide immerwieder ausführt? dann genau so
läuft das programm ab. beide funktionen werden immerwieder ausgeführt!

Autor: Marco Gerlach (macro)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ok jetzt hab ichs tatsächlich verstanden. alles klar. kein fehler! sieht
eben nur so aus. ich finds nutürlich ein wenig bescheurt vom studio,
dass da nicht der sinn des asm-codes verstanden wird und dem benutzter
wenigstens vorgegaukelt wird, dass alles so läuft wie gewünscht.

aber noch was anderes

habt ihr irgendeine idee welche ursachen in frage kommen, wenn
code-teile mal richtig und mal falsch ausgeführt werden
bsp:
variante a: 999938/1000000=0.999938
variante b: 999938/1000000=0.499969

Autor: A.K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Debugger hat keine Chance. Wo technisch nur ein Funktionsaufruf ist,
hat er naturgemäss Probleme, diesen Aufruf mehreren Quellecodezeilen
zuzuordnen. Das ist der wohlbekannte Pferdefuss bei eingeschalteter
Code-Optimierung des Compilers.

Weshalb in solchem Kontext auch immer der Tip gegeben wird, bei Nutzung
des Debuggers die Code-Optimierung durch den Compiler abzuschalten. Was
bei Controllern freilich bisweilen Grenzen hat, wenn dabei das ROM
platzt.

Die Situation ist also nicht ideal, sie kann es nicht sein. Es kann
sogar das Paradox entstehen, dass ein mies optimierender Compiler im
praktischen Betrieb mit Debuggern angenehmer wirkt als ein gut
optimierender.

Autor: Marco Gerlach (macro)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
und zum anderen problem gibts keine meinungen?

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Welches ,,andere Problem''?

Autor: Marco Gerlach (macro)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich hab da noch ein Problem:

"aber noch was anderes

habt ihr irgendeine idee welche ursachen in frage kommen, wenn
code-teile mal richtig und mal falsch ausgeführt werden
bsp:
variante a: 999938/1000000=0.999938
variante b: 999938/1000000=0.499969"

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mach mal einen separaten Thread dafür auf (hier im Forum)
mit einem nachvollziehbaren Programmstückchen.

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.