Forum: Compiler & IDEs Problem mit Optimirung -Os


von Pier S. (bigpier)


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.
1
volatile uint16_t ServoPos = 2000;
2
uint8_t  DATARX[20];
3
4
if (flag & (1<<RxComp))
5
{
6
    cli();
7
    ServoPos = (DATARX[4]);
8
    ServoPos =(ServoPos<<8);
9
    ServoPos |= (DATARX[3]);
10
    OCR1A = ServoPos;
11
    flag &= ~(1<<RxComp);
12
    sei();
13
}

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

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


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:
1
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.

von yalu (Gast)


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.

von Pier S. (bigpier)


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

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.