Probleme mit -O2

OP #283938
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?
OP #283942
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.
OP #283944
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren