Hallo Ich hab ein komisches Problem an dem ich schon seit heute Vormittag sitze und einfach nicht die Lösung finde. Ich schreibe eine Bibliothek für ein LCD mit mehreren Grafikfunktionen. Nun hab ich ein Problem mit einer Bitshifting Operation, wo ich einfach nicht den Fehler finde. Folgender Code (auszugsweise): uint8_t pattern = 0x66; // 0b 0110 0110 pattern >>=2 ; // um 2 Bit nach rechts schieben Nun würde ich mir das folgende Ergebnis erwarten: 1001 1001 Ich erhalte jedoch 0001 1001 Es sieht so aus als würde die Operation die 2 Bit nur rechts hinausschieben jedoch nicht links wieder einfügen, wie das bei der Assember Funktion rol bzw ror ist. Wie kann ich den GCC dennoch davon überzeugen so ein bitweises Shiften durchzuführen? MfG Gregor
@ Gregor (Gast) >uint8_t pattern = 0x66; // 0b 0110 0110 >pattern >>=2 ; // um 2 Bit nach rechts schieben >Nun würde ich mir das folgende Ergebnis erwarten: >1001 1001 Wieso? >Ich erhalte jedoch 0001 1001 Was vollkommen korrekt ist. ;-) MFG Falk
Gregor schrieb: > Nun hab ich ein Problem mit einer Bitshifting Operation Falk Brunner schrieb: > Was vollkommen korrekt ist. ;-) schieben (shiften) ist nun mal kein rotieren. MfG
Die Operatoren << und >> sind Shift -Operatoren. Deine rol und ror sind rotate -Befehle. Shift == Schieben Rotate == Rotieren Rotieren musst du in C selber bauen oder mal Inline-Assembler testen. Bei [1] scheint die richtige Funktion von Inline-Assembler angezweifelt zu werden, also probiere es vorher aus, oder baue dir selbst eine Funktion in C. [1] http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&p=454612 [2] http://www.rn-wissen.de/index.php/Inline-Assembler_in_avr-gcc
void ror(uint8_t &var) { if(var & 0x01) { var >>=1; var |= 0x80; } else { var >>=1; } } Keine Garantie auf Richtigkeit :-)
Danke für eure Antworten. Ich hab da wohl zwei Dinge miteinander vermischt. Ich werde die Funktion von Floh ausprobieren Vielen dank nochmal
Floh schrieb: > void ror(uint8_t &var) > { Erheblich kürzer, auch im generierten Code:
1 | var = (var << 7) | (var >> 1); |
Schneller in Punkto Taktzyklen ist es allerdings nicht, braucht nur weniger Speicher. Andreas PS: das mit den Taktzyklen war natürlich jetzt AVR-zentrisch, der OP hatte aber nicht erwähnt, dass er das verwenden würde. Andere Architekturen können andere Ergebnisse liefern, der x86-GCC z.B. macht bei -O2 aus meiner Zeile oben sogar wirklich ein ROL (um 7 Bits, also effektiv ROR), im Gegensatz zu der Variante mit Verzweigung, die mehr oder weniger "wörtlich" übersetzt wird.
@ Andreas Ferber (aferber) Oder gleich [1] befolgen, bei mir hat es geklappt. Die Vermutung aus [1], dass das nur schiebt und nicht rotiert, stimmt nicht auf meinem x86_64 zumindest nicht. Bei einem µC sollte man das wohl nochmal simulieren oder mit ein paar LEDs testen...
eklige Tunke schrieb: > Bei [1] scheint die richtige Funktion von Inline-Assembler angezweifelt > zu werden Jein, es wird nur darauf hingewiesen, dass die Instruktionen ROR und ROL eben nicht Rotate Right/Left sind, sondern Rotate Right/Left through Carry. Darum reicht eine Instruktion nicht aus, da man sich eben um das Carry-Loch kümmern muss. mfG Markus
Markus J. schrieb: > Darum reicht eine Instruktion nicht aus, da man sich eben um das > Carry-Loch kümmern muss. Ah, jetzt verstehe ich. Scheint bei x86 aber anders zu sein.
eklige Tunke schrieb: >> Darum reicht eine Instruktion nicht aus, da man sich eben um das >> Carry-Loch kümmern muss. > Ah, jetzt verstehe ich. Scheint bei x86 aber anders zu sein. Yepp. Bei x86 gibt es separate Instruktionen zur Rotation mit Carry, RCR und RCL. Andreas
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.