avr-gcc verwendet sbiw um einen 8-Bit Rueckgabewert zu vergleichen.

Gast #3199141
Lesenswert?

Hi,

mein avr-gcc hat mit unter Ubuntu 13.04 mit -O2 folgendes produziert:
1
  
2

3
    void bar(void)
4
    {
5
        if( foo() == 1 )
6
      94:   0e 94 53 00     call    0xa6    ; 0xa6 <foo>
7
      98:   01 97           sbiw    r24, 0x01       ; 1
8
      9a:   11 f0           breq    .+4             ; 0xa0 <bar+0xc>
9
            return 1;
10
        uint8_t a = foo();
11
      9c:   0c 94 53 00     jmp     0xa6    ; 0xa6 <foo>
12
      a0:   08 95           ret
13
     
14
    000000a2 <main>:
15
        return 2;
16
    }
17
     
18
    void main(void)
19
    {
20
        bar();
21
      a2:   0c 94 4a 00     jmp     0x94    ; 0x94 <bar>
22
     
23
    000000a6 <foo>:
24
    #include <stdint.h>
25
    uint8_t foo(void)
26
    {
27
        return 1;
28
    }
29
      a6:   81 e0           ldi     r24, 0x01       ; 1
30
      a8:   08 95           ret

Wie zu sehen ist, gibt foo() einen 8-Bit grossen Wert in r24 zurueck. 
Danach testet der Compiler das Ergebnis mit sbiw, welched r24:r25 
anschaut. Das ganze hat mir in einem komplexeren Programm schon Probleme 
bereitet. Wenn ich die if-Abfrage durch
1
uint8_t baz=foo(); if( baz == 1 ) {...}
ersetzte, wird cpi zum Vergleichen genommen und das Ergebnis ist wie 
erwartet.

Bug im Compiler oder nur mein Tunnelblick?

Gruss,
Tobias
#3199175
Lesenswert?

Tobias Schneider schrieb:

> Wie zu sehen ist, gibt foo() einen 8-Bit grossen Wert in r24 zurueck.
> Danach testet der Compiler das Ergebnis mit sbiw, welched r24:r25
> anschaut. Das ganze hat mir in einem komplexeren Programm schon Probleme
> bereitet.

Da würde ich doch glatt mal schätzen, dass du es mit Funktionsprototypen 
nicht so genau nimmst (bzw. die entsprechenden Compilerwarnungen 
ignorierst) und du so den Compiler zu der Standard-Annahme zwingst, dass 
jede Funktion von der er nichts genaueres weiß einen 16-Bit int zurück 
liefert, den er dann natürlich auch einem 16-Bit Vergleich unterziehen 
muss.
Gast #3199507
Lesenswert?

Gna, Ihr habt absolut recht.

Hatte das urspruenglich in nem groesseren Programm, den Header nicht 
eingebunden und die eine Warnung uebersehen...

Ja, der Compiler hat dann als Rueckgabetyp int(?) eingesetzt und den 
16-Bit Vergleich durchgefuehrt.

Zu mindest ich hab jetzt meine Lektion gelernt ;)

Danke fuer die Hinweise.

Gruss,
Tobias
#3199546
Lesenswert?

1:0 für -Werror
Ja, es gibt gcc-Warnungen, die sind eher lästig und im konkreten Fall 
total überflüssig. Sind aber i.d.R. nicht viele und durch einen Satz 
Klammern o.ä. behoben.
In viel viel mehr Fällen sind die Warnungen sehr berechtigt. Da hilft 
-Werror gegen das Übersehen.

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