Forum: Compiler & IDEs Byte umdrehen


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Dirk Wiebel (Gast)


Lesenswert?

Hallo Forum,

stehe gerade auf dem Schlauch:

gibt es einen einfachen Weg, ein Byte "umzudrehen", so dass

128 -> 1
64  -> 2
32  -> 4
16  -> 8
...

Grund: Der "umgekehrte" PortA des Atmega16 und Designprobleme...

Any hints?

Gruss,
Dirk

von ??? (Gast)


Lesenswert?

register einfach mit 0xFF XOR nehmen...

von Peter D. (peda)


Lesenswert?

;input: r16
;output: r17

ldi r17, 1
loop:
ror r16
rol r17
brcc loop


Peter

von Werner Hoch (Gast)


Lesenswert?

Hi,

Der C-Code ist nicht effektiv, Ich wollte damals nur keinen Assembler
mit einbinden.

uint8_t
mirrorbyte(uint8_t value) {
  uint8_t ret=0, i;
  for (i=0x80; i ; i>>=1) {
    if (value & 0x01)
      ret |= i;
    value >>= 1;
  }
  return ret;
}

mfg
werner

von Stefan (Gast)


Lesenswert?

Also XOR tuts nicht.
Das dreht die Polarität um, aber nicht die Bitreihenfolge.

Wie willst Du es denn machen? Mit Assembler oder in C?

In Assembler würde ich 2 Register über das Carry rotieren lassen:

Das Byte, was geändert werden soll, steht in R16, das Ergebnis später
in R17:

   rol   R16      ;Bit 7 von R16 ins Carry
   ror   R17      ;Carry in Bit 7 von R17

.. und diese 2 Befehle 8 mal wiederholen.

In C geht es natürlich auch ...

Stefan

von Dirk Wiebel (Gast)


Lesenswert?

Hallo,

danke fuer die Tipps. Ich habe noch folgendes ergooglet:

   n = ((n >>  1) & 0x55555555) | ((n <<  1) & 0xaaaaaaaa);
   n = ((n >>  2) & 0x33333333) | ((n <<  2) & 0xcccccccc);
   n = ((n >>  4) & 0x0f0f0f0f) | ((n <<  4) & 0xf0f0f0f0);
   n = ((n >>  8) & 0x00ff00ff) | ((n <<  8) & 0xff00ff00);
   n = ((n >> 16) & 0x0000ffff) | ((n << 16) & 0xffff0000);

Werde morgen mal schauen, was am schnellsten durchlaeuft.

Gruss,
Dirk

von Joerg Wunsch (Gast)


Lesenswert?

Die Diskussion hatten wir schon mal in de.sci.electronics.

Die Variante mit der Schleife ist die codesparendste.  Für 8 bit ist
sie vermutlich auch mit die schnellste, für 32 bit braucht sie schon
recht lange.

Interessant ist dieser Trick aus der BSD fortune database:

   n = ((n >>  1) & 0x55555555) | ((n <<  1) & 0xaaaaaaaa);
   n = ((n >>  2) & 0x33333333) | ((n <<  2) & 0xcccccccc);
   n = ((n >>  4) & 0x0f0f0f0f) | ((n <<  4) & 0xf0f0f0f0);
   n = ((n >>  8) & 0x00ff00ff) | ((n <<  8) & 0xff00ff00);
   n = ((n >> 16) & 0x0000ffff) | ((n << 16) & 0xffff0000);

                -- C code which reverses the bits in a word.

...nur falls es mal jemand für paar Bits mehr braucht. ;-)

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.