mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik AVR-GCC Bug? if (uint16_t-Typ == 0).


Autor: Michael S. (michael-dj2tk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich habe ein Problem mit dem AVR-gcc und seiner Optimierung. Angenommen 
sei folgender Ausschnitt aus einem C-Code:
    volatile static uint16_t readBytes;

    if ( (readBytes) == 0 )
    {
        PORTD = 0x01; // Beispiel
    }

Ohne irgendeine Optmierung (-Ox weggelassen) erzeugt gcc diesen Code:
lds  r24, 0x0060
lds  r25, 0x0061
sbiw  r24, 0x00  
breq  .+2        
rjmp  .+244      
der für mich auch ok aussieht. Mit Optimierung (-O, -O2, -Os) erzeugt er 
das hier:
lds  r24, 0x0060
lds  r25, 0x0061
or  r24, r25
brne  .+4        
Ich denke dass dieser Code falsch ist - in den Registern r24 und r25 
befinden sich das High- und Low-Byte der uint16 Variable. Eine 
Oder-Operation ergibt für mich als Test auf Null keinen Sinn (im 
Gegensatz zum unoptimierten Fall s.o.).

Diese Änderung ergibt sich erst, wenn ein O-Parameter angegeben wird. 
Wenn ich versuche, die Optimierungen mit -fxxx Parametern nachzubauen, 
bekomme ich das Problem nicht, allerdings ändert sich die Code-Größe 
auch nicht.

Das ganze ist natürlich in ein größeres Projekt eingebettet, so dass ich 
Optimierung haben will, schon aus Geschwindigkeitsgründen. Allerdings 
habe ich noch einen (diffusen) Fehler in der Software, die von der 
Optimierungsstufe abhängig ist, und diesen suche ich nun.

Die Frage ist nun, habe ich bei obigem Beispiel irgendwo einen 
Denkfehler? Warum "funktioniert" die Optimierung nur, wenn ich einen 
O-Parameter angebe, und nicht mit den f-Parametern? Auch über Literatur 
zu dem Thema und Tipps aus der Praxis wäre ich dankbar.

Vielen Dank schon mal für die Hilfe,
Michael

PS: Eingesetzte Version: avr-gcc 4.2.2 aus der Ubuntu 8.04 Standard 
Installation, avr-libc 1.4.7-1 (auch aus Ubuntu). Binutils 2.18-3. Eine 
eigene Toolchain zu erstellen wollte ich eigentlich vermeiden, aber wäre 
wohl einer der nächsten Schritte falls ich keine bessere Idee habe...

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Michael S. wrote:

> Eine Oder-Operation ergibt für mich als Test auf Null keinen Sinn

Für mich schon. Der Code ist völlig korrekt. Das Ergebnis dieser 
Operation ist genau und nur dann 0 wenn beide Register 0 sind, und das Z 
Flag gibt diesen Sachverhalt wieder.

Autor: Benedikt K. (benedikt) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Für mich gibt das schon einen Sinn:
Wenn die 16bit Variable 0 ist, sind weder in r24 noch in r25 Bits 
gesetzt. Demzufolge ist das Ergebnis der Oder Operation auch 0 und das 
brne wird ausgeführt.

Autor: Michael S. (michael-dj2tk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oh Mist, ich wusste ich stand auf dem Schlauch - gedanklich eine 
Und-Operation durchgeführt. Peinlich...

Danke für die schnelle Antwort! Dann werd ich mal weitersuchen...

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Worauf in diesem Zusammenhang allerdings zu achten ist: Wenn readBytes 
den Wert 0x0100 hat und im Interrupt auf 0x00FF runtergezählt wird, dann 
kann es vorkommen, dass der Test das untere Byte vor und das obere Byte 
nach dem Interrupt läd und damit fälschlicherweise auf 0 erkennt.

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.