www.mikrocontroller.net

Forum: Compiler & IDEs Problem mit Optimirung -Os


Autor: Pier S. (bigpier)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Guten morgen,
ich muß wiedermal um Hilfe Bitten.
Ich habe ein Problem mit einem kleinen Stück Code bei dem ich einfach 
nict verstehe was ich falsch mache.
volatile uint16_t ServoPos = 2000;
uint8_t  DATARX[20];

if (flag & (1<<RxComp))
{
    cli();
    ServoPos = (DATARX[4]);
    ServoPos =(ServoPos<<8);
    ServoPos |= (DATARX[3]);
    OCR1A = ServoPos;
    flag &= ~(1<<RxComp);
    sei();
}


Wenn ich das Ganze mit -O0 kompiliere dann kommt am Ende in der Variable 
ServoPos der richtige wert an.
Wenn ich allerdings mit -Os kompiliere dann steht in ServoPos immer 0.

Im Disassembler schaut das Ganze so Aus
68:           if (flag & (1<<RxComp))
+000000D5:   91800161    LDS       R24,0x0161     Load direct from data 
space
+000000D7:   FF80        SBRS      R24,0          Skip if bit in 
register set
+000000D8:   CFFC        RJMP      PC-0x0003      Relative jump
70:             cli();
+000000D9:   94F8        CLI                      Global Interrupt 
Disable
72:             ServoPos = (DATARX[4]);
+000000DA:   93500102    STS       0x0102,R21     Store direct to data 
space
+000000DC:   93400101    STS       0x0101,R20     Store direct to data 
space
73:             ServoPos =(ServoPos<<8);
+000000DE:   91800101    LDS       R24,0x0101     Load direct from data 
space
+000000E0:   91900102    LDS       R25,0x0102     Load direct from data 
space
+000000E2:   2F98        MOV       R25,R24        Copy register
+000000E3:   2788        CLR       R24            Clear Register
+000000E4:   93900102    STS       0x0102,R25     Store direct to data 
space
+000000E6:   93800101    STS       0x0101,R24     Store direct to data 
space
74:             ServoPos |= (DATARX[3]);
+000000E8:   91800101    LDS       R24,0x0101     Load direct from data 
space
+000000EA:   91900102    LDS       R25,0x0102     Load direct from data 
space
+000000EC:   2B82        OR        R24,R18        Logical OR
+000000ED:   2B93        OR        R25,R19        Logical OR
+000000EE:   93900102    STS       0x0102,R25     Store direct to data 
space
+000000F0:   93800101    STS       0x0101,R24     Store direct to data 
space
75:             OCR1A = ServoPos;
+000000F2:   91800101    LDS       R24,0x0101     Load direct from data 
space
+000000F4:   91900102    LDS       R25,0x0102     Load direct from data 
space
+000000F6:   93900089    STS       0x0089,R25     Store direct to data 
space
+000000F8:   93800088    STS       0x0088,R24     Store direct to data 
space
76:             flag &= ~(1<<RxComp);
+000000FA:   91800161    LDS       R24,0x0161     Load direct from data 
space
+000000FC:   7F8E        ANDI      R24,0xFE       Logical AND with 
immediate
+000000FD:   93800161    STS       0x0161,R24     Store direct to data 
space
77:             sei();

Nun zu meiner Frage was mach ich Falsch
Ich verwende das Avr Studio 4.18 mit WinAVR 20030313
AVR_LIBC_VERSION_STRING__ "1.6.6"

Vielen Dank für Eure Hilfe

Peter

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

Bewertung
0 lesenswert
nicht lesenswert
Pier S. schrieb:

> Wenn ich das Ganze mit -O0 kompiliere dann kommt am Ende in der Variable
> ServoPos der richtige wert an.

Allerdings sehr umständlich (auch noch bei anderen Optimierungsstufen),
weil dein ServoPos volatile ist.  Damit zwingst du den Compiler, es
für sämtliche Zwischenergebnisse jeweils zu speichern und danach neu
zu lesen.

Falls ServoPos volatile sein muss, würde ich das aber innerhalb des
if-Blocks in einer temporären Variablen zusammenbauen, die am Ende
nach ServoPos geschoben wird.  Oder man eliminiert die diversen
Zwischenergebnisse und schreibt gleich:
ServoPos = (DATARX[4] << 8) | DATARX[3];

Aber selbst dann bleibt eine überflüssige Rücklese-Operation zum
Beschreiben des OCR1A.

> Wenn ich allerdings mit -Os kompiliere dann steht in ServoPos immer 0.

Das lässt sich aus dem gezeigten Codeschnipsel nicht sagen.  Das
sieht erst einmal unverdächtig aus.  Offenbar steht in ServoPos
ja auch nicht der Initialwert (2000), sondern es wird tatsächlich
etwas anderes geschrieben.

p.s.: Bezeichner in Großbuchstaben verwendet man per Konvention
für Makros, damit man diese sofort erkennen kann.  Du scheinst mit
DATARX aber eine Variable zu bezeichnen.

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wo wird DATARX beschrieben? Sicher in einem Interrupthandler. Jedenfalls
ist im Assemblercode kein einziger Zugriff auf DATARX zu finden.
Deswegen muss möglicherweise auch DATARX als volatile deklariert werden.

Autor: Pier S. (bigpier)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn DATARX auch volatile deklariert  dann funktioniert das Ganze.
Vielen Dank für Eure Hilfe !!
Jörg Du hast  mit dem groß schreiben recht ich versuche es mir zu 
merken.


Danke und noch einen schönen Tag

Gruß
Peter

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.