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
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.
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
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.
"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
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.
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
Wenn der Compiler schon darauf kommt lsr zu verwenden, dann sollte es auch nicht mehr so schwierig sein ihm ror beizubringen (Peephole-Optimierung?).
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.