Assemblerbefehle ROL /ROR in C?

Gast #179218
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.
Gast #179219
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
Gast #179220
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.
#179221
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
Gast #179222
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.
#179223
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
Gast #179225
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.

Antwort schreiben

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.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.