Forum: Compiler & IDEs Probleme mit -O2


von Fritz G. (fritzg)


Lesenswert?

Bin ich doof, oder der Compiler?

Folgender Code:
1
  beflen = 0;
2
  pos = 0;
3
  waitstart = 1;
4
  ccount = 0;
5
  parity = 0;
6
  beftype = 255;
7
  // 1 heisst warten auf 0 0 Startfolge, erste 0
8
  // 2 warten auf zweite 0
9
  // 3 warten auf Befehlstyp, Länge
10
  do      //mainloop
11
  {
12
    while (!(usart_unread_data ()))
13
    {
14
      c = usart_getc ();
15
16
      if (waitstart != 0)
17
      {
18
        if (waitstart == 1)
19
        {
20
          if (c == 0)
21
            waitstart = 2;
22
        }
23
        else
24
        {
25
          if (waitstart == 2)
26
          {
27
            if (c == 0)
28
            {
29
              waitstart = 3;
30
              ccount = 1;
31
            }
32
            else
33
              waitstart = 1;
34
          }
35
          else  // muss wohl waitstart 3 sein
36
          {
37
            parity += c;
38
            ccount++;
39
            switch (ccount)
40
            {
41
            case 2:
42
              beftype = c;
43
              break;
44
            case 3:
45
              shipadr = c << 8;
46
              break;
47
            case 4:
48
              shipadr += c;
49
              break;
50
            case 5:
51
              if ((beftype == 1) || (beftype == 2))
52
              {
53
                beflen = c * 2;
54
                waitstart = 0;
55
                pos = 0;
56
              }
57
            }
58
59
            data[beflen] = c;
60
61
          }
62
        }
63
64
      }
65
      else
66
      {
67
        data[beflen] = c;
68
        parity += c;
69
        if (pos < beflen) ;
70
      }
71
    }
72
73
74
  }
75
  while (1);

Mit -O2 optimiert er alles nach
c = usart_getc ();
weg.
Ersetze ich das
    while (!(usart_unread_data ()))
durch ein if ... dann tut es.

Hier das Assemblerlisting:
1
406:zentrale.c    ****   beflen = 0;
2
 407:zentrale.c    ****   pos = 0;
3
 408:zentrale.c    ****   waitstart = 1;
4
 409:zentrale.c    ****   ccount = 0;
5
 410:zentrale.c    ****   parity = 0;
6
 411:zentrale.c    ****   beftype = 255;
7
 412:zentrale.c    ****   // 1 heisst warten auf 0 0 Startfolge, erste
8
0
9
 413:zentrale.c    ****   // 2 warten auf zweite 0
10
 414:zentrale.c    ****   // 3 warten auf Befehlstyp, Länge
11
 415:zentrale.c    ****   do      //mainloop
12
 416:zentrale.c    ****   {
13
 417:zentrale.c    ****     while (!(usart_unread_data ()))
14
 549                 .LM62:
15
 550                 /*DEBUG: 0x7    2  16 */
16
 551 012a 0E94 0000     call usart_unread_data
17
 552                 /*DEBUG: 0x9    2  8 */
18
 553 012e 8823          tst r24
19
 554                 /*DEBUG: 0xa    1  24 */
20
 555 0130 E1F7          brne .L76
21
 418:zentrale.c    ****     {
22
 419:zentrale.c    ****       c = usart_getc ();
23
 557                 .LM63:
24
 558                 /*DEBUG: 0xb    1  16 */
25
 559 0132 0E94 0000     call usart_getc
26
 560                 /*DEBUG: 0xd    2  8 */
27
 561 0136 F9CF          rjmp .L76
28
 562                 /* epilogue: frame size=0 */
29
 563                 /* epilogue: noreturn */
30
 564                 /* epilogue end (size=0) */
31
 565                 /* function main size 18 (14) */

Weiss da jemand Rat?

von Fritz G. (fritzg)


Lesenswert?

Im Asseblerlistung fehlt oben noch die Zeile

547                 .L76:

und im C File oben:
  do      //mainloop
  {

von Unbekannter (Gast)


Lesenswert?

Der Compiler hat immer recht. Offensichtlich ist Dein hier geposteter
Code nicht vollständig.

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


Lesenswert?

Guck dir vor allem das tatsächliche Assemblerlisting an,
nicht den Disassembler-Krempel.

von Fritz G. (fritzg)


Lesenswert?

@Unbekannter:
Der Code ist vollständig genug, glaub mir!

Habs schon gefunden, ein printf() oder sonstwas am Ende reicht, dann
tuts wieder.

War ein typischer Fall von: Schön was er da macht, aber irgendwie
braucht er die Ergebnisse eh nicht, also schmeiss ich alles weg.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Der Code ist mit Sicherheit nicht vollständig genug - wie sind denn
beispielsweise die Variablen deklariert? War da nicht was mit
"volatile" oder so?

von Fritz G. (fritzg)


Lesenswert?

Der Rest vom Code:
1
  uint8_t beflen, pos, waitstart, c, ccount, parity, beftype;
2
  uint8_t data[256];
3
  uint16_t shipadr;

Da gibts nix mit volatile, weil da noch keine Variblen mit Interrupt
verändert werden.

In dem Code tut die Art und Größe der Variblen übrigens nichts zur
Sache.

Ich hab mir lediglich das Assemblerlistung zu früh angesehen.

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.