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


von Christian Spratte (Gast)


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

von Rufus T. Firefly (Gast)


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.

von Christian Spratte (Gast)


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

von Rufus T. Firefly (Gast)


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.

von Peter D. (peda)


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

von Rufus T. Firefly (Gast)


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.

von Peter D. (peda)


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

von Andreas S. (andreas) (Admin) Benutzerseite


Lesenswert?

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

von Rufus T. Firefly (Gast)


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.

von Jörg Wunsch (Gast)


Lesenswert?

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

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.