www.mikrocontroller.net

Forum: Compiler & IDEs Assemblerbefehle ROL /ROR in C?


Autor: Christian Spratte (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

gibt es die Befehle ROL und ROR (rotieren eines Byte) auch in C oder
muss ich die wenn ich sie brauche durch Inline-Assembler einbauen?
Wenn's nicht direkt geht - wie mache ich das dann ausgehend von einer
Char-Variable?

Viele Grüße Christian

Autor: Rufus T. Firefly (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Da wirst Du mit Inline-Assembler arbeiten müssen. Rotation ist keine in
C standardmäßig verfügbare Operation.
Ginge es nur ums Schieben, dann sähe das anders (nämlich so: << und >>)
aus.
Sich eine Rotation in C selbstzubasteln ist recht ineffizient.

  char quelle;
  char ziel;

  // Rotation in die eine Richtung
  ziel = (quelle << 1) | ((quelle & 0x80) >> 7);

  // Rotation andersrum
  ziel = (quelle >> 1) | ((quelle & 1) << 7);

Diese selbstgebaute Rotation rotiert nicht durch das Carry-Flag und
wird auf Prozessoren ohne "barrel-shifter" je nach Compiler recht
langsam. Das ließe sich allerdings umgehen, vorausgesetzt, daß der
Prozessor multiplizieren kann:

  // Rotation in die eine Richtung
  ziel = (quelle * 2) | ((quelle & 0x80) / 0x80);

  // Rotation andersrum
  ziel = (quelle / 2) | ((quelle & 1) * 0x80);

Ein brauchbar optimierender Compiler sollte das aber auch von selbst
auf die Reihe bekommen.

Autor: Christian Spratte (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Rufus,

Danke erstmal für diese Möglichkeit - die Schiebebefehle waren mir
schon bekannt - nutze ich im Moment auch. Kannst Du mir evtl. auch
sagen wie das das Rollen mit Inline-Assembler funktioniert?
Viele Grüße

Christian

Autor: Rufus T. Firefly (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das ist vom verwendeten Compiler und Prozessor abhängig ...

Mangels eigener Nutzung selbigens kann ich Dir da nicht weiterhelfen,
das wird aber sicherlich jemand anderes aus diesem Forum hier
hinbekommen.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"Sich eine Rotation in C selbstzubasteln ist recht ineffizient."

Das halte ich aber für ein Gerücht.

Eine echte Rotation gibt es beim AVR-Asssembler außerdem nicht, es wird
immer über C rotiert. Du mußt also immer noch von C nach Bit 0 (oder 7)
kopieren.

Die Frage ist eigentlich, wozu braucht man die Rotation ???

Meistens reicht das << bzw. >> völlig.


Peter

Autor: Rufus T. Firefly (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Recht ineffizient ist sie, weil statt eines ROR/ROL-Befehles eben 'ne
ganze Latte Befehle erforderlich sind - die von mir geposteten
Codefragmente werden vom Compiler sicherlich nicht in ein, zwei Befehle
übersetzt.

Selbst wennn es nur ROR/ROL durchs Carry-Flag geben sollte, dürfte das
nachträgliche Übertragen des Carry-Flags nach Bit0/7 kaum mehr als
eines Befehles bedürfen, so daß so etwas in Assembler sicherlich
effizienter ist, als die Übersetzung des C-Konstruktes.

Rotationsoperatoren kommen IMHO in Verschlüsselungsalgorithmen des
öfteren vor.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also unter "'ne ganze Latte Befehle" würde ich das doppelte und mehr
verstehen.

In Assembler braucht man 3 Befehle:

 lsr   r25
 brcc  label
 ori   r25, 0x80
label:


Und in C sähe das gleiche so aus:

 u8 temp = val;
 val >>= 1;
 if( temp & 0x01 )
   val |= 0x80;

Das sind dann 4 Assembler-Befehle, d.h. der Assemblercode ist gerade
mal nur 25% kleiner:

 66:   98 2f           mov     r25, r24
 u8 temp = val;
 val >>= 1;
 68:   96 95           lsr     r25
 if( temp & 0x01 )
 6a:   80 fd           sbrc    r24, 0
   val |= 0x80;
 6c:   90 68           ori     r25, 0x80


Peter

Autor: Andreas Schwarz (andreas) (Admin) Benutzerseite Flattr this
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn der Compiler schon darauf kommt lsr zu verwenden, dann sollte es
auch nicht mehr so schwierig sein ihm ror beizubringen
(Peephole-Optimierung?).

Autor: Rufus T. Firefly (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was soll der Compiler anderes als LSR aus einer Zeile mit >> machen?

Ob die "peephole"-Optimierung ein ROR aus dem ganzen Konstrukt
bastelt, kann ich nicht beurteilen*. Kann man das (als
Normalsterblicher) beim GCC in irgendeiner Weise beeinflussen?
Nach dem Motto Code-Fragment wird von Hand optimiertem Code-Fragment
gegenüber gestellt und der Compiler ersetzt dann entsprechend?

@Peter: Mit Deinem so formulierten C-Code gibst Du dem Compiler ja
schon den einen oder anderen Hinweis, auch verwendest Du eine
Hilfsvariable.
Wie sieht denn das Übersetzungsresultat* des von mir geposteten Codes
aus?


*) (beide) Habe hier keinen AVR-GCC verfügbar, kann daher nur "im
Trockenen" spekulieren.

Autor: Jörg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nö, man müsste das dem Compiler schon lehren, also sprich: den
Compilercode selbst modifizieren.  Können könnte er das dann
sicherlich.

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]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [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.