Forum: Compiler & IDEs AVR GCC switch statement springt wirr


von Wolfgang (Gast)


Lesenswert?

Hallo,

vielleicht kann mir einer der Experten helfen:

Ich habe folgendes Problem:
Eine Stateengine ist als zyklisch zu rufende Funktion mit einer globalen 
Variablen und einem davon abgeleitetem switch() kodiert. Rufe ich diese 
Funktion auf, springt mir der Simulator absolut wirr da drin rum - und 
zwar nicht das übliche Verschieben des Optimizers, sondern wie ich im 
Disassembler und an den ausgeführten Codepartikeln sehen, macht er auch 
wirklich Schrott.

Ich habe dann folgende Versuche unternommen:
- clean und rebuild all.
- Datei aus dem prject gelöscht und wieder neu aufgenommen.
- Optimize bis auf -o1 zurückgenommen - keine Änderung.
- Quelltext auf Sonderzeichen abgesucht - keine Auffälligkeiten.
- Umstellen der case-Blöcke: keine Änderung.
- Einkopieren der Funktion in die aufrufende Routine: Und siehe da, es 
läuft.

Momentan bin ich etwas ratlos, woran das liegen könnte; und es ist ja 
nicht das erste AVR-Programm, welches ich schreibe.

Servus Wolfgang, www.opendcc.de

von Zulu (Gast)


Lesenswert?

Hört sich nach einem Stack-Problem an. Speicher läuft über.

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Wie stark ist das SRAM deines µC schon durch DATA und BSS ausgenutzt, 
lass dir mal eine Statistik nach dem Kompilieren ausgeben?

Hast du viele dynamisch zur Laufzeit angelegte Variablen, die ja auf dem 
Stack zusätzlich angelegt werden? Eventuell sind es zu viele, so dass 
der Stack zerschossen wird.

von Wolfgang (Gast)


Lesenswert?

Hallo,

danke für den Hinweis, leider kein Treffer: Siumlator stopped: 
Stackpointer bei 0x10ED, Data endet bei 0x0D98. Also noch ewig viel 
Platz.

Servus Wolfgang

von Wolfgang (Gast)


Lesenswert?

Ich habe mal C Code und das was ich auf Maschinenebene sehe hier 
angehängt:

Das Statement xbee_rx.header.len = data << 8 kommt im Disassembler 
sofort nach dem Funktionsaufruf, dürfte aber nur bei case 1 kommen.

Gruß Wolfgang
1
t_cr_task run_xbee_client(void)
2
  {
3
    #warning xbee_task still incomplete!
4
5
    rx_fifo_ready();
6
7
    unsigned char data;
8
    while (rx_fifo_ready())  
9
      {
10
        data = rx_fifo_read();                 // reads one byte
11
12
        switch(bytes_rcvd++)
13
          {
14
            case 0:
15
                if (data == XBEE_PKT_START)
16
                  {
17
                    xbee_rx.header.delimiter = data;
18
                  }
19
                // else ignore data
20
                break;
21
22
            case 1:
23
                xbee_rx.header.len = data << 8;
24
                break;
25
26
            case 2:
27
                xbee_rx.header.len |= data;
28
                // xbee_rx.header.len = ntohs(xbee_rx.header.len);   // resolve endiness
29
                bytes_left = xbee_rx.header.len;
30
31
                if ( bytes_left > XBEE_MAX_DATA_LEN )
32
                  {
33
                    bytes_left = 0;
34
                    bytes_rcvd = 0;
35
                    // xbee_rx_err(xbee);
36
                    #warning handle error missing
37
                  }
38
39
                break;
40
            case 3:
41
                xbee_rx.header.cmd_id = data;
42
                x_index = 0;
43
                bytes_left--;
44
                break;
45
46
            default:
47
                if (bytes_left == 1)
48
                  {
49
                    if ( xbee_checksum(&xbee_rx) != data)
50
                      {
51
                        bytes_rcvd = 0;
52
                        // xbee_rx_checksum_err(xbee);
53
                        #warning handle error missing
54
                      }
55
                    else
56
                      {
57
                        PORTB = 0x35;
58
                        // now process this packet
59
                        xbee_rx.data[x_index] = 0;           // set end delimiter
60
                        xbee_rx.data[x_index++] = 0x03;           // set end delimiter
61
                        xbee_rx.data[x_index++] = 0x04;           // set end delimiter
62
                        xbee_rx.data[x_index++] = 0x05;           // set end delimiter
63
                        xbee_rx.data[x_index++] = 0x06;           // set end delimiter
64
                        xbee_rx.data[x_index++] = 0x0F;           // set end delimiter
65
                        xbee_rx.data[x_index++] = 0;           // set end delimiter
66
                        parse_xbee_packet();
67
                      }
68
                    bytes_rcvd = 0;
69
                  }
70
                else
71
                  {
72
                    xbee_rx.data[x_index++] = data;
73
                    bytes_left--;
74
                  }
75
                break;
76
          }
77
      }



1
@00007474: run_xbee_client
2
367:        {
3
+00007474:   92BF        PUSH    R11              Push register on stack
4
+00007475:   92CF        PUSH    R12              Push register on stack
5
+00007476:   92DF        PUSH    R13              Push register on stack
6
+00007477:   92EF        PUSH    R14              Push register on stack
7
+00007478:   92FF        PUSH    R15              Push register on stack
8
+00007479:   930F        PUSH    R16              Push register on stack
9
+0000747A:   931F        PUSH    R17              Push register on stack
10
+0000747B:   93CF        PUSH    R28              Push register on stack
11
+0000747C:   93DF        PUSH    R29              Push register on stack
12
370:          rx_fifo_ready();
13
+0000747D:   940E2CBB    CALL    0x00002CBB       Call subroutine
14
394:                      xbee_rx.header.len = data << 8;
15
+0000747F:   E1CD        LDI     R28,0x1D         Load immediate
16
+00007480:   E0DD        LDI     R29,0x0D         Load immediate
17
428:                              PORTB = 0x35;
18
+00007481:   E355        LDI     R21,0x35         Load immediate
19
+00007482:   2EB5        MOV     R11,R21          Copy register
20
431:                              xbee_rx.data[x_index++] = 0x03;           // set end delimiter
21
+00007483:   E043        LDI     R20,0x03         Load immediate
22
+00007484:   2EC4        MOV     R12,R20          Copy register
23
432:                              xbee_rx.data[x_index++] = 0x04;           // set end delimiter
24
+00007485:   E034        LDI     R19,0x04         Load immediate
25
+00007486:   2ED3        MOV     R13,R19          Copy register
26
433:                              xbee_rx.data[x_index++] = 0x05;           // set end delimiter
27
+00007487:   E025        LDI     R18,0x05         Load immediate
28
+00007488:   2EE2        MOV     R14,R18          Copy register
29
434:                              xbee_rx.data[x_index++] = 0x06;           // set end delimiter
30
+00007489:   E096        LDI     R25,0x06         Load immediate
31
+0000748A:   2EF9        MOV     R15,R25          Copy register
32
435:                              xbee_rx.data[x_index++] = 0x0F;           // set end delimiter

von Karl H. (kbuchegg)


Lesenswert?

Wolfgang schrieb:
> Ich habe mal C Code und das was ich auf Maschinenebene sehe hier
> angehängt:
>
> Das Statement xbee_rx.header.len = data << 8 kommt im Disassembler
> sofort nach dem Funktionsaufruf,

Darauf darfst du nichts geben.
Im Listing taucht die C-Zeile in dieser Form auf.
Aber im Assembler Code sieht man, dass hier lediglich 2 Register mit 
Zahlen gefüllt werden. Wahrscheinlich ist das die Speicheradresse von 
xbee_rx.header.len die die Datenflussanalyse ausgewählt hat um in einem 
Register ständig vorgehalten zu werden.

Überhaupt:
Auch die nächsten Assemblersequenzen machen nicht das, was im C-Source 
Code steht. Der Compiler hat anscheinend die Konstanten, die in diesen 
Ausdrücken vorkommen, in Registern, die gerade frei sind, 
zwischengeparkt.

Wobei: Seltsam ist das schon. Schliesslich werden da ein Haufen Register 
mit Konstanten blockiert von denen noch nicht einmal feststeht, ob sie 
je zum Zuge kommen.

von Wolfgang (Gast)


Lesenswert?

Ui, ich glaube, da habe ich mich doch irreführen lassen. Der Compiler 
macht zwar die Registerbelegungen, verwirft das dann aber in der 
Minderzahl der Fälle. Baue ich da zusätzlich Portausgabe rein (wo er 
nicht vorbei darf), dann sieht es schon wieder besser aus.

Danke, Wolfgang

von Zulu (Gast)


Lesenswert?

Könnte es sein, das der Compiler Grund zu der Annahme hat, das immer nur 
der der case 1: und der else-Teil im default ausgeführt wird? Das er 
deswegen aus dem data << 8 das laden einer Konstante macht, weil er zu 
wissen meint, das data immer einen bestimmten Wert haben wird. Also 
0x1D. Andererseits woher nimmt er dann die 0x0D vom Lowbyte?

Ein bischen komisch ist das schon. Es fällt auf, das (bis auf data) 
sämtliche Variablen die den Ablauf ändern könnten ausserhalb der 
Funktion deklariert sein müssen. Auch die Funktion xbee_checksum müsste 
dann immer ein Resultat != data liefern. Ich tippe zwar eher nicht 
darauf, aber ehe ich von einem Compilerfehler ausgehe, gehe ich davon 
aus, das ich der Dummbatz bin.

Mich würde auch mal interessieren wie der Asm-Code weitergeht. Ob 
tatsächlich zurück zum while springt oder nicht.

von Wolfgang (Gast)


Lesenswert?

Hier die ganze routine:
1
@00007474: run_xbee_client
2
367:        {
3
+00007474:   92BF        PUSH    R11              Push register on stack
4
+00007475:   92CF        PUSH    R12              Push register on stack
5
+00007476:   92DF        PUSH    R13              Push register on stack
6
+00007477:   92EF        PUSH    R14              Push register on stack
7
+00007478:   92FF        PUSH    R15              Push register on stack
8
+00007479:   930F        PUSH    R16              Push register on stack
9
+0000747A:   931F        PUSH    R17              Push register on stack
10
+0000747B:   93CF        PUSH    R28              Push register on stack
11
+0000747C:   93DF        PUSH    R29              Push register on stack
12
370:          rx_fifo_ready();
13
+0000747D:   940E2CBB    CALL    0x00002CBB       Call subroutine
14
394:                      xbee_rx.header.len = data << 8;
15
+0000747F:   E1CD        LDI     R28,0x1D         Load immediate
16
+00007480:   E0DD        LDI     R29,0x0D         Load immediate
17
428:                              PORTB = 0x35;
18
+00007481:   E355        LDI     R21,0x35         Load immediate
19
+00007482:   2EB5        MOV     R11,R21          Copy register
20
431:                              xbee_rx.data[x_index++] = 0x03;           // set end delimiter
21
+00007483:   E043        LDI     R20,0x03         Load immediate
22
+00007484:   2EC4        MOV     R12,R20          Copy register
23
432:                              xbee_rx.data[x_index++] = 0x04;           // set end delimiter
24
+00007485:   E034        LDI     R19,0x04         Load immediate
25
+00007486:   2ED3        MOV     R13,R19          Copy register
26
433:                              xbee_rx.data[x_index++] = 0x05;           // set end delimiter
27
+00007487:   E025        LDI     R18,0x05         Load immediate
28
+00007488:   2EE2        MOV     R14,R18          Copy register
29
434:                              xbee_rx.data[x_index++] = 0x06;           // set end delimiter
30
+00007489:   E096        LDI     R25,0x06         Load immediate
31
+0000748A:   2EF9        MOV     R15,R25          Copy register
32
435:                              xbee_rx.data[x_index++] = 0x0F;           // set end delimiter
33
+0000748B:   E00F        LDI     R16,0x0F         Load immediate
34
+0000748C:   C07A        RJMP    PC+0x007B        Relative jump
35
375:              data = rx_fifo_read();                 // reads one byte
36
+0000748D:   940E2CC4    CALL    0x00002CC4       Call subroutine
37
+0000748F:   2F18        MOV     R17,R24          Copy register
38
383:              switch(bytes_rcvd++)
39
+00007490:   91800C86    LDS     R24,0x0C86       Load direct from data space
40
+00007492:   5F8F        SUBI    R24,0xFF         Subtract immediate
41
+00007493:   93800C86    STS     0x0C86,R24       Store direct to data space
42
+00007495:   5081        SUBI    R24,0x01         Subtract immediate
43
+00007496:   3081        CPI     R24,0x01         Compare with immediate
44
+00007497:   F079        BREQ    PC+0x10          Branch if equal
45
+00007498:   3081        CPI     R24,0x01         Compare with immediate
46
+00007499:   F038        BRCS    PC+0x08          Branch if carry set
47
+0000749A:   3082        CPI     R24,0x02         Compare with immediate
48
+0000749B:   F079        BREQ    PC+0x10          Branch if equal
49
+0000749C:   91900D1B    LDS     R25,0x0D1B       Load direct from data space
50
+0000749E:   3083        CPI     R24,0x03         Compare with immediate
51
+0000749F:   F521        BRNE    PC+0x25          Branch if not equal
52
+000074A0:   C01E        RJMP    PC+0x001F        Relative jump
53
386:                      if (data == XBEE_PKT_START)
54
+000074A1:   371E        CPI     R17,0x7E         Compare with immediate
55
+000074A2:   F009        BREQ    PC+0x02          Branch if equal
56
+000074A3:   C063        RJMP    PC+0x0064        Relative jump
57
388:                          xbee_rx.header.delimiter = data;
58
+000074A4:   93100D1C    STS     0x0D1C,R17       Store direct to data space
59
+000074A6:   C060        RJMP    PC+0x0061        Relative jump
60
+000074A7:   92100D1D    STS     0x0D1D,R1        Store direct to data space
61
+000074A9:   8319        STD     Y+1,R17          Store indirect with displacement
62
+000074AA:   C05C        RJMP    PC+0x005D        Relative jump
63
398:                      xbee_rx.header.len |= data;
64
+000074AB:   2F81        MOV     R24,R17          Copy register
65
+000074AC:   E090        LDI     R25,0x00         Load immediate
66
+000074AD:   91200D1D    LDS     R18,0x0D1D       Load direct from data space
67
+000074AF:   91300D1E    LDS     R19,0x0D1E       Load direct from data space
68
+000074B1:   2B82        OR      R24,R18          Logical OR
69
+000074B2:   2B93        OR      R25,R19          Logical OR
70
+000074B3:   93900D1E    STS     0x0D1E,R25       Store direct to data space
71
+000074B5:   93800D1D    STS     0x0D1D,R24       Store direct to data space
72
400:                      bytes_left = xbee_rx.header.len;
73
+000074B7:   93800D1B    STS     0x0D1B,R24       Store direct to data space
74
402:                      if ( bytes_left > XBEE_MAX_DATA_LEN )
75
+000074B9:   3881        CPI     R24,0x81         Compare with immediate
76
+000074BA:   F408        BRCC    PC+0x02          Branch if carry cleared
77
+000074BB:   C04B        RJMP    PC+0x004C        Relative jump
78
404:                          bytes_left = 0;
79
+000074BC:   92100000    STS     0x0000,R1        Store direct to data space
80
+000074BE:   C038        RJMP    PC+0x0039        Relative jump
81
412:                      xbee_rx.header.cmd_id = data;
82
+000074BF:   93100D1F    STS     0x0D1F,R17       Store direct to data space
83
413:                      x_index = 0;
84
+000074C1:   92100C96    STS     0x0C96,R1        Store direct to data space
85
+000074C3:   C040        RJMP    PC+0x0041        Relative jump
86
418:                      if (bytes_left == 1)
87
+000074C4:   3091        CPI     R25,0x01         Compare with immediate
88
+000074C5:   F5A1        BRNE    PC+0x35          Branch if not equal
89
420:                          if ( xbee_checksum(&xbee_rx) != data)
90
+000074C6:   E18C        LDI     R24,0x1C         Load immediate
91
+000074C7:   E09D        LDI     R25,0x0D         Load immediate
92
+000074C8:   940E740B    CALL    0x0000740B       Call subroutine
93
+000074CA:   1781        CP      R24,R17          Compare
94
+000074CB:   F559        BRNE    PC+0x2C          Branch if not equal
95
+000074CC:   B8B5        OUT     0x05,R11         Out to I/O location
96
430:                              xbee_rx.data[x_index] = 0;           // set end delimiter
97
+000074CD:   91800C96    LDS     R24,0x0C96       Load direct from data space
98
+000074CF:   2FE8        MOV     R30,R24          Copy register
99
+000074D0:   E0F0        LDI     R31,0x00         Load immediate
100
+000074D1:   5EE4        SUBI    R30,0xE4         Subtract immediate
101
+000074D2:   4FF2        SBCI    R31,0xF2         Subtract immediate with carry
102
+000074D3:   82C4        STD     Z+4,R12          Store indirect with displacement
103
+000074D4:   5F8F        SUBI    R24,0xFF         Subtract immediate
104
+000074D5:   2FE8        MOV     R30,R24          Copy register
105
+000074D6:   E0F0        LDI     R31,0x00         Load immediate
106
+000074D7:   5EE4        SUBI    R30,0xE4         Subtract immediate
107
+000074D8:   4FF2        SBCI    R31,0xF2         Subtract immediate with carry
108
+000074D9:   82D4        STD     Z+4,R13          Store indirect with displacement
109
+000074DA:   5F8F        SUBI    R24,0xFF         Subtract immediate
110
+000074DB:   2FE8        MOV     R30,R24          Copy register
111
+000074DC:   E0F0        LDI     R31,0x00         Load immediate
112
+000074DD:   5EE4        SUBI    R30,0xE4         Subtract immediate
113
+000074DE:   4FF2        SBCI    R31,0xF2         Subtract immediate with carry
114
+000074DF:   82E4        STD     Z+4,R14          Store indirect with displacement
115
+000074E0:   5F8F        SUBI    R24,0xFF         Subtract immediate
116
+000074E1:   2FE8        MOV     R30,R24          Copy register
117
+000074E2:   E0F0        LDI     R31,0x00         Load immediate
118
+000074E3:   5EE4        SUBI    R30,0xE4         Subtract immediate
119
+000074E4:   4FF2        SBCI    R31,0xF2         Subtract immediate with carry
120
+000074E5:   82F4        STD     Z+4,R15          Store indirect with displacement
121
+000074E6:   5F8F        SUBI    R24,0xFF         Subtract immediate
122
+000074E7:   2FE8        MOV     R30,R24          Copy register
123
+000074E8:   E0F0        LDI     R31,0x00         Load immediate
124
+000074E9:   5EE4        SUBI    R30,0xE4         Subtract immediate
125
+000074EA:   4FF2        SBCI    R31,0xF2         Subtract immediate with carry
126
+000074EB:   8304        STD     Z+4,R16          Store indirect with displacement
127
+000074EC:   5F8F        SUBI    R24,0xFF         Subtract immediate
128
---- xbee_if.c ------------------------------------------------------------------------------------
129
436:                              xbee_rx.data[x_index++] = 0;           // set end delimiter
130
+000074ED:   2FE8        MOV     R30,R24          Copy register
131
+000074EE:   E0F0        LDI     R31,0x00         Load immediate
132
+000074EF:   5EE4        SUBI    R30,0xE4         Subtract immediate
133
+000074F0:   4FF2        SBCI    R31,0xF2         Subtract immediate with carry
134
+000074F1:   8214        STD     Z+4,R1           Store indirect with displacement
135
+000074F2:   5F8F        SUBI    R24,0xFF         Subtract immediate
136
+000074F3:   93800C96    STS     0x0C96,R24       Store direct to data space
137
437:                              parse_xbee_packet();
138
+000074F5:   940E7468    CALL    0x00007468       Call subroutine
139
439:                          bytes_rcvd = 0;
140
+000074F7:   92100C86    STS     0x0C86,R1        Store direct to data space
141
+000074F9:   C00D        RJMP    PC+0x000E        Relative jump
142
443:                          xbee_rx.data[x_index++] = data;
143
+000074FA:   91800C96    LDS     R24,0x0C96       Load direct from data space
144
+000074FC:   2FE8        MOV     R30,R24          Copy register
145
+000074FD:   E0F0        LDI     R31,0x00         Load immediate
146
+000074FE:   5EE4        SUBI    R30,0xE4         Subtract immediate
147
+000074FF:   4FF2        SBCI    R31,0xF2         Subtract immediate with carry
148
+00007500:   8314        STD     Z+4,R17          Store indirect with displacement
149
+00007501:   5F8F        SUBI    R24,0xFF         Subtract immediate
150
+00007502:   93800C96    STS     0x0C96,R24       Store direct to data space
151
444:                          bytes_left--;
152
+00007504:   5091        SUBI    R25,0x01         Subtract immediate
153
+00007505:   93900D1B    STS     0x0D1B,R25       Store direct to data space
154
373:          while (rx_fifo_ready())  
155
+00007507:   940E2CBB    CALL    0x00002CBB       Call subroutine
156
+00007509:   2388        TST     R24              Test for Zero or Minus
157
+0000750A:   F009        BREQ    PC+0x02          Branch if equal
158
+0000750B:   CF81        RJMP    PC-0x007E        Relative jump
159
473:        }
160
+0000750C:   EF8F        SER     R24              Set Register
161
+0000750D:   EF9F        SER     R25              Set Register
162
+0000750E:   91DF        POP     R29              Pop register from stack
163
+0000750F:   91CF        POP     R28              Pop register from stack
164
+00007510:   911F        POP     R17              Pop register from stack
165
+00007511:   910F        POP     R16              Pop register from stack
166
+00007512:   90FF        POP     R15              Pop register from stack
167
+00007513:   90EF        POP     R14              Pop register from stack
168
+00007514:   90DF        POP     R13              Pop register from stack
169
+00007515:   90CF        POP     R12              Pop register from stack
170
+00007516:   90BF        POP     R11              Pop register from stack
171
+00007517:   9508        RET                      Subroutine return

von Zulu (Gast)


Lesenswert?

Hmmm. Also er hat die C-Codezeilen umgestellt. Soweit aber ok.

Was genau ist das Problem?
>wie ich im Disassembler und an den ausgeführten Codepartikeln sehen, macht >er 
auch wirklich Schrott.

Funktioniert das Programm garnicht oder irritiert Dich das herumspringen 
nur?

von Wolfgang K. (opendcc)


Lesenswert?

Hallo,

das Programm funktioniert. Ich hatte mich wirklich verwirren lassen - im 
Single-Step von AVR Studio werden sogar Portausgabe innerhalb des 
switch-statements angezeigt (d.h. die RUN-Markierung steht auf der 
Anweisung PORTB = 0x35), jedoch werden diese nicht ausgeführt.

Gruß Wolfgang

von (prx) A. K. (prx)


Lesenswert?

Wolfgang K. schrieb:

> Single-Step von AVR Studio werden sogar Portausgabe innerhalb des
> switch-statements angezeigt (d.h. die RUN-Markierung steht auf der
> Anweisung PORTB = 0x35), jedoch werden diese nicht ausgeführt.

Was du woran erkennst?

von Wolfgang K. (opendcc)


Lesenswert?

Wenn ich drüber steppe, ändert der Port seinen Zustand nicht.

WOlfgang

von (prx) A. K. (prx)


Lesenswert?

Dann wird der Port wohl nicht als Ausgang definiert sein. Jedenfalls hat 
das erkennbar wenig mit dem Compiler zu tun, allenfalls mit dem 
Simulator.

von Karl H. (kbuchegg)


Lesenswert?

Wolfgang K. schrieb:
> Wenn ich drüber steppe, ändert der Port seinen Zustand nicht.


Das sollte sich nach einem Blick ins Assemblerlisting auch geklärt 
haben.

Es ist lediglich die Anzeige falsch.
Der Compiler hat die Anweisung

     PORTB = 0x35;

in 2 Teile gesplittet. Die 0x35 hat er sich in einem Register 
zurechtgelegt und die eigentliche Portausgabe blieb an der korrekten 
Stelle.

Unglücklicherweise ist die Source-Code Zeile

     PORTB = 0x35;

beim Splitten an die Stelle gerutscht, an der sich der Compiler die 0x35 
im Register vorbelegt hat.
Damit siehst du im Debugger zwar die Zeile, aber unter der Tuchent 
passiert eigentlich ganz was anderes.

-> Wenn du optimierten Code debuggst, darfst du keinen Jota mehr drauf 
geben, was im C-Source Code dort steht. Das kann alles zerpflückt und 
umsortiert worden sein. Statements können in sich auseinandergerissen 
und in anderer Reihenfolge (auch untereinander gemischt) neu 
zusammengesetzt worden sein.

von Wolfgang (Gast)


Lesenswert?

Das habe ich inzwischen auch gemerkt :-) wobei der Optimizer gegenüber 
früher schon mehr rumrührt. Manchmal ist es schon fast unheimlich, was 
der so treibt - Hut ab vor den Leuten, die das machen.

Servus Wolfgang

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.