Forum: Compiler & IDEs Vergleich wird 16-bittig ausgeführt (avr-gcc)


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Olaf Bellheim (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Professor: ATtiny2313
avr-gcc: (AVR_8_bit_GNU_Toolchain_3.4.2_939) 4.7.2

Ich habe eine Frage an die C-Gurus, und zwar habe ich folgendes 
"Problem".
Wie man im Assembler-Listing sehen kann, übersetzt avr-gcc diesen 
Vergleich 16-bittig.
Warum ist das so und kann man es abstellen?
1
if( statusbyte.rc5_bit ^ ((RC5_INP & RC5_PIN) ? 1 : 0) ) {
2
  ...
3
}
4
5
IN        R19,0x13       In from I/O location
6
IN        R18,0x10       In from I/O location
7
BST       R19,2          Bit store from register to T
8
CLR       R22            Clear Register
9
BLD       R22,0          Bit load from T to register
10
LDI       R23,0x00       Load immediate
11
BST       R18,4          Bit store from register to T
12
CLR       R20            Clear Register
13
BLD       R20,0          Bit load from T to register
14
LDI       R21,0x00       Load immediate
15
CP        R22,R20        Compare
16
CPC       R23,R21        Compare with carry
17
BREQ      PC+0x20        Branch if equal

von Mark B. (markbrandis)


Bewertung
2 lesenswert
nicht lesenswert
1
if( statusbyte.rc5_bit ^ ((RC5_INP & RC5_PIN) ? 1 : 0) ) {
2
    ...
3
}

Probier's mal mit gescheitem Code. Nein, möglichst viel in eine Zeile zu 
quetschen ist nicht gescheit.

von Kirby (Gast)


Bewertung
-2 lesenswert
nicht lesenswert
Mark B. schrieb:
>
1
> if( statusbyte.rc5_bit ^ ((RC5_INP & RC5_PIN) ? 1 : 0) ) {
2
>     ...
3
> }
4
>
>
> Probier's mal mit gescheitem Code. Nein, möglichst viel in eine Zeile zu
> quetschen ist nicht gescheit.

Außer für Leute, die 'Professor: ATtiny2313' schreiben.

von Peter D. (peda)


Bewertung
2 lesenswert
nicht lesenswert
Warum willst nicht, daß das jemand compilieren kann?

Zu Codefetzen gehören minimal die Definitionen und Macros.

von Yalu X. (yalu) (Moderator)


Bewertung
1 lesenswert
nicht lesenswert
Was die Symbole statusbyte, RC5_INP und RC5_PIN bedeuten, ist wohl dein
Geheimnis, also kann man nur raten. Ich habe versucht, die fehlende
Information aus dem generierten Assemblercode zu rekonstruieren.

Wenn ich damit richtig liege, tut folgender C-Code dasselbe:

1
  uint8_t rc5inp = RC5_INP;
2
  if(statusbyte.rc5_bit)
3
    rc5inp = ~rc5inp;
4
  if(rc5inp & RC5_PIN) {
5
    ...
6
  }


GCC 6.2.0 macht daraus

1
  in r24,0x13
2
  sbic 0x10,4
3
  com r24
4
  sbrs r24,2
5
  rjmp ...

was IMHO nicht weiter optimiert werden kann.


Übrigens:

Statt

1
(ausdruck) ? 1 : 0

kann man auch schreiben

1
(bool)(ausdruck)

: Bearbeitet durch Moderator
von Sebastian V. (sebi_s)


Bewertung
0 lesenswert
nicht lesenswert
Yalu X. schrieb:
> Übrigens:
>
> Statt
>
> (ausdruck) ? 1 : 0
>
> kann man auch schreiben
>
> (bool)(ausdruck)

In C? Da gibts bool nur seit C99 und selbst dann ist es nur ein Integer 
imho.

von (prx) A. K. (prx)


Bewertung
0 lesenswert
nicht lesenswert
Sebastian V. schrieb:
> In C? Da gibts bool nur seit C99 und selbst dann ist es nur ein Integer
> imho.

"bool" ist per stdint.h definiert als _Bool und ist eine Integer, die 
nur die Wert 0 und 1 annehmen kann: "When any scalar value is converted 
to _Bool, the result is 0 if the value compares equal to 0; otherwise, 
the result is 1."

: Bearbeitet durch User
von Johann L. (gjlayde) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
A. K. schrieb:
> "bool" ist per stdint.h definiert

stdbool.h

von Peter D. (peda)


Bewertung
0 lesenswert
nicht lesenswert
Sebastian V. schrieb:
>> Statt
>>
>> (ausdruck) ? 1 : 0
>>
>> kann man auch schreiben
>>
>> (bool)(ausdruck)

oder
1
 !!(ausdruck)

von Yalu X. (yalu) (Moderator)


Bewertung
1 lesenswert
nicht lesenswert
Sebastian V. schrieb:
>> (bool)(ausdruck)
>
> In C? Da gibts bool nur seit C99 und selbst dann ist es nur ein Integer
> imho.

Wir haben jetzt das Jahr 2016 ;-)

Peter D. schrieb:
> oder !!(ausdruck)

So hat man's vor 1999 gemacht.

von A. S. (achs)


Bewertung
0 lesenswert
nicht lesenswert
Olaf Bellheim schrieb:
> warum ist das so und kann man es abstellen?

nennt sich integral promotion und kann meist mit Compilerschaltern 
abgeschaltet werden. Dann sind allerdings überläufe bei u16=u8a+u8b ohne 
casts oder Umstellung möglich.

von S. R. (svenska)


Bewertung
0 lesenswert
nicht lesenswert
Olaf Bellheim schrieb:
> Wie man im Assembler-Listing sehen kann, übersetzt avr-gcc diesen
> Vergleich 16-bittig.

Weil auf AVR der Integer nur 16 Bit breit ist. Du kannst einen der 
Operanden auf 32 Bit casten, dann sollte ein 32 Bit breiter Vergleich 
dabei rauskommen.

von Olaf Bellheim (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Danke, der Cast hats gebracht. Jetzt siehts schon viel besser aus.
1
IN        R18,0x13       In from I/O location
2
IN        R19,0x10       In from I/O location
3
SWAP      R19            Swap nibbles
4
ANDI      R19,0x01       Logical AND with immediate
5
BST       R18,2          Bit store from register to T
6
CLR       R18            Clear Register
7
BLD       R18,0          Bit load from T to register
8
CP        R19,R18        Compare
9
BREQ      PC+0x20        Branch if equal
Gruß Olaf

von Yalu X. (yalu) (Moderator)


Bewertung
0 lesenswert
nicht lesenswert
Nur interessehalber: Hat mein Vorschlag von oben

1
uint8_t rc5inp = RC5_INP;
2
  if(statusbyte.rc5_bit)
3
    rc5inp = ~rc5inp;
4
  if(rc5inp & RC5_PIN) {
5
    ...
6
  }

nicht zum erwünschten Erfolg geführt?

Denn der würde ja noch einmal 8 Bytes einsparen :)

von Olaf Bellheim (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Yalu X. schrieb:
> Nur interessehalber: Hat mein Vorschlag von oben

Ich denke nicht, ich möchte den Flankenwechsel in der Bitmitte erkennen.
Das ganze basiert auf Peter Dannegers RC5-Code 
Beitrag "Fernbedien RC5 Empfänger"

von Adib (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Olaf Bellheim schrieb:
> Danke, der Cast hats gebracht. Jetzt siehts schon viel besser

Wie sieht denn der Code jetzt aus? Was genau sind d nn die Macros?

Ps: im C sind alle Bit-operationen mit int-operanden definiert.

Grüße, Adib.
--

von Markus F. (mfro)


Bewertung
2 lesenswert
nicht lesenswert
Adib schrieb:
> Ps: im C sind alle Bit-operationen mit int-operanden definiert.

Nein.

In C sind alle Operationen auf "schmaleren" Datentypen als int als 
Operationen auf int definiert (integer promotion).

Ein optimierender Compiler darf das abkürzen, solange das Ergebnis 
dasselbe bleibt, wie wenn er integer promotion durchgeführt hätte.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.