# Wie kann man Hi-Byte Low-Byte spiegeln?



## Klärmolch (10 Dezember 2010)

Hi,
wie kann ich innerhalb eines Wortes die Bytes spiegeln, bzw. in einem Doppelwort die Worte?

M0.0 = M1.7
M0.1 = M1.6
...... =  ......
M0.7 = M1.0

Mit rotieren habe ich es nicht hinbekommen.

Vielen Dank!

Klaus


----------



## Taddy (10 Dezember 2010)

Hallo

TAW
TAD


----------



## Dr.M (10 Dezember 2010)

Taddy schrieb:


> Hallo
> 
> TAW
> TAD



Diese Befehle tauschen zwar die Bytes, spiegeln aber nicht die Bits


----------



## Approx (10 Dezember 2010)

Klärmolch schrieb:


> Hi,
> wie kann ich innerhalb eines Wortes die Bytes spiegeln, bzw. in einem Doppelwort die Worte?
> 
> M0.0 = M1.7
> ...


Im Prinzip kann man es ja auch so machen, wie Du es schon geschrieben hast! Wenn Du das Umwandeln der Bits mehrfach brauchst, dann schreib Dir nen kleinen FC mit einer IN-Variable (Wort oder Doppelwort) und einer OUT-Variable (Format entsprechend dem IN). 
Im FC geht das IN-Wort über dem Umweg einer Temp-Variable auf das OUT-Wort wie oben beschrieben. Den FC kann man dann mehrfach aufrufen, wie einen Rotierbefehl...
Approx


----------



## Copyright (10 Dezember 2010)

Hallo,

also wenn du das Wort bzw. Doppelwort bitweise haben möchtest würde ich das auch so machen. Das ist recht einfach und kann bibliothekfähig gemacht werden in einem FC.

Solltest du das Wort bzw. Doppelwort im Int bzw. Dint Format haben wollen, ist es warscheinlich wesentlich aufwändiger, müsste aber prinzipiell auch gehen.

Copy


----------



## Thomas_v2.1 (10 Dezember 2010)

Mit den Bit-Befehlen der S7 wird das zwar schneller gehen, aber mit einer kleinen Schleife und schieben/rotieren könnte man das auch so machen:

```
L     0                           // mit 0 initialisieren
      T     #out

      L     16                          // 16 Bits
loop: T     #i

      L     #out
      SLW   1                           // und nach links shiften
      T     #out

      L     #in
      UW    W#16#1                      // Bit ausmaskieren
      L     #out
      OW    
      T     #out                        // in out ein"verodern"

      L     #in                         // Eingang weiterschieben
      SRW   1
      T     #in

      L     #i
      LOOP  loop
```


----------



## PN/DP (10 Dezember 2010)

*zwei Schritt vor und ein zurück ...*

So sollte es gehen für 16-Bit-Word (nicht getestet):

```
// A1|   Akku1 H-Word     Akku1 L-Word
L    2          //Anzahl Schiebungen für alle SLW ohne Operand
L    #In_Word   // . | ................ FEDCBA9876543210

SLW  1          // F | ................ EDCBA9876543210.
RRDA            // . | F............... .EDCBA9876543210
SLW             // E | F............... DCBA9876543210..
RRDA            // . | EF.............. .DCBA9876543210.
SLW             // D | EF.............. CBA9876543210...
RRDA            // . | DEF............. .CBA9876543210..
SLW             // C | DEF............. BA9876543210....
RRDA            // . | CDEF............ .BA9876543210...
SLW             // B | CDEF............ A9876543210.....
RRDA            // . | BCDEF........... .A9876543210....
SLW             // A | BCDEF........... 9876543210......
RRDA            // . | ABCDEF.......... .9876543210.....
SLW             // 9 | ABCDEF.......... 876543210.......
RRDA            // . | 9ABCDEF......... .876543210......
SLW             // 8 | 9ABCDEF......... 76543210........
RRDA            // . | 89ABCDEF........ .76543210.......

SLW             // 7 | 89ABCDEF........ 6543210.........
RRDA            // . | 789ABCDEF....... .6543210........
SLW             // 6 | 789ABCDEF....... 543210..........
RRDA            // . | 6789ABCDEF...... .543210.........
SLW             // 5 | 6789ABCDEF...... 43210...........
RRDA            // . | 56789ABCDEF..... .43210..........
SLW             // 4 | 56789ABCDEF..... 3210............
RRDA            // . | 456789ABCDEF.... .3210...........
SLW             // 3 | 456789ABCDEF.... 210.............
RRDA            // . | 3456789ABCDEF... .210............
SLW             // 2 | 3456789ABCDEF... 10..............
RRDA            // . | 23456789ABCDEF.. .10.............
SLW             // 1 | 23456789ABCDEF.. 0...............
RRDA            // . | 123456789ABCDEF. .0..............
SLW             // 0 | 123456789ABCDEF. ................
RRDA            // . | 0123456789ABCDEF ................

SRD  16         // . | ................ 0123456789ABCDEF
T    #Out_Word
```
(alle SLW ohne Anzahl-Operand schieben 2 Bit - steht in Akku2)

Für 32-Bit-DWORD einfach L-Word und H-Word getrennt spiegeln und dann vertauscht zusammensetzen.
Vielleicht gibt es auch noch eine etwas kürzere Variante mit 4x Byte spiegeln.

Harald


----------



## PN/DP (10 Dezember 2010)

*In einem Byte/Word/Doppelword die Reihenfolge der Bits umdrehen/spiegeln (S7)*



> Wie kann man in einem Byte/Word/Doppelword die Reihenfolge der Bits umdrehen/spiegeln?
> (aus der Bitfolge 76543210 soll die Bitfolge 01234567 werden)


Zunächst die Bit-Reihenfolge in den 4 Teil-Bytes spiegeln und bei Word/Doppelword danach 
die in sich gespiegelten Bytes in die gespiegelte Reihenfolge bringen.
Die blauen Operationen für Byte/Word/Doppelword anpassen.
( TAK = Tausche Akku1 mit Akku2 / *.* = dieses Bit ist 0 )

*Doppelword* spiegeln:

```
[COLOR="seagreen"]// H-H-Byte H-L-Byte L-H-Byte L-L-Byte
                       // [B]31----24 23----16 15-----8 7------0[/B][/COLOR]
[COLOR="blue"]L    #In_DWord[/COLOR]         [COLOR="seagreen"]// [B]76543210 76543210 76543210 76543210[/B][/COLOR]

PUSH                   [COLOR="seagreen"]// #In_DWord von Akku1 in Akku2 merken[/COLOR]
UD   DW#16#F0F0F0F0    [COLOR="seagreen"]// 7654.... 7654.... 7654.... 7654....[/COLOR]
SRD  4                 [COLOR="seagreen"]// ....7654 ....7654 ....7654 ....7654[/COLOR]
TAK                    [COLOR="seagreen"]// [B]76543210 76543210 76543210 76543210[/B][/COLOR]
UD   DW#16#0F0F0F0F    [COLOR="seagreen"]// ....3210 ....3210 ....3210 ....3210[/COLOR]
SLD  4                 [COLOR="seagreen"]// 3210.... 3210.... 3210.... 3210....[/COLOR]
OD                     [COLOR="seagreen"]// [B]32107654 32107654 32107654 32107654[/B][/COLOR]

PUSH                   [COLOR="seagreen"]// Zwischenergebnis Akku1 in Akku2 merken[/COLOR]
UD   DW#16#CCCCCCCC    [COLOR="seagreen"]// 32..76.. 32..76.. 32..76.. 32..76..[/COLOR]
SRD  2                 [COLOR="seagreen"]// ..32..76 ..32..76 ..32..76 ..32..76[/COLOR]
TAK                    [COLOR="seagreen"]// [B]32107654 32107654 32107654 32107654[/B][/COLOR]
UD   DW#16#33333333    [COLOR="seagreen"]// ..10..54 ..10..54 ..10..54 ..10..54[/COLOR]
SLD  2                 [COLOR="seagreen"]// 10..54.. 10..54.. 10..54.. 10..54..[/COLOR]
OD                     [COLOR="seagreen"]// [B]10325476 10325476 10325476 10325476[/B][/COLOR]

PUSH                   [COLOR="seagreen"]// Zwischenergebnis Akku1 in Akku2 merken[/COLOR]
UD   DW#16#AAAAAAAA    [COLOR="seagreen"]// 1.3.5.7. 1.3.5.7. 1.3.5.7. 1.3.5.7.[/COLOR]
SRD  1                 [COLOR="seagreen"]// .1.3.5.7 .1.3.5.7 .1.3.5.7 .1.3.5.7[/COLOR]
TAK                    [COLOR="seagreen"]// [B]10325476 10325476 10325476 10325476[/B][/COLOR]
UD   DW#16#55555555    [COLOR="seagreen"]// .0.2.4.6 .0.2.4.6 .0.2.4.6 .0.2.4.6[/COLOR]
SLD  1                 [COLOR="seagreen"]// 0.2.4.6. 0.2.4.6. 0.2.4.6. 0.2.4.6.[/COLOR]
OD                     [COLOR="seagreen"]// [B]01234567 01234567 01234567 01234567[/B]
// hier sind jetzt alle 4 Bytes in sich gespiegelt[/COLOR]

[COLOR="blue"]TAD[/COLOR]                    [COLOR="seagreen"]// [B]0------7 8-----15 16----23 24----31[/B][/COLOR]
[COLOR="blue"]T    #Out_DWord[/COLOR]        [COLOR="seagreen"]// gespiegeltes DWord ausgeben[/COLOR]
```

*Word* spiegeln:

```
[COLOR="seagreen"]// ...   Code wie oben bis:
// hier sind jetzt alle 4 Bytes in sich gespiegelt[/COLOR]

[COLOR="blue"]TAW[/COLOR]                    [COLOR="seagreen"]// 24----31 16----23 [B]0------7 8-----15[/B][/COLOR]
[COLOR="blue"]T    #Out_Word[/COLOR]         [COLOR="seagreen"]// gespiegeltes L-Word ausgeben[/COLOR]
```

*Byte* spiegeln:

```
[COLOR="seagreen"]// ...   Code wie oben bis:
// hier sind jetzt alle 4 Bytes in sich gespiegelt[/COLOR]

[COLOR="blue"]T    #Out_Byte[/COLOR]         [COLOR="seagreen"]// gespiegeltes L-L-Byte ausgeben[/COLOR]
```

Harald


----------



## Klärmolch (10 Dezember 2010)

Hallo,
ich dachte es gibt einen einzigen direkten Befehl der das kann.
Nun ist mir einiges klarer.
Ich werde die von Euch angeführten Beispiele mal ausprobieren.

@Taddy
Das kann ich auch gebrauchen, S7 <--> alte Kuhnke

Vielen Dank an Euch.

Gruß
Klaus


----------



## Corosop15 (10 Dezember 2010)

Klärmolch schrieb:


> Hallo,
> ich dachte es gibt einen einzigen direkten Befehl der das kann.


 
Warum definierst Du dann Deine Frage nicht so?


----------



## Klärmolch (10 Dezember 2010)

Hi,
es hätte nur den Ablauf des Tread geändert.
Die Antwort lautet offensichlich nein.
Daraufhin hätte ich dann nach einer geeigneten Lösung gefragt.
Habe mir einen FC geschrieben und über Tempvariablen getauscht.


Gruß
Klaus


----------



## borromeus (10 Dezember 2010)

PN/DP schrieb:


> Zunächst die Bit-Reihenfolge in den 4 Teil-Bytes spiegeln und bei Word/Doppelword danach
> die in sich gespiegelten Bytes in die gespiegelte Reihenfolge bringen.
> Die blauen Operationen für Byte/Word/Doppelword anpassen.
> ( TAK = Tausche Akku1 mit Akku2 / *.* = dieses Bit ist 0 )
> ...


 
Das letzte Mal habe ich sowas "gehört": war von Puccini!
Absolut feinste Klinge.
Das muss man echt sagen!


----------



## Thomas_v2.1 (10 Dezember 2010)

borromeus schrieb:


> Das letzte Mal habe ich sowas "gehört": war von Puccini!
> Absolut feinste Klinge.
> Das muss man echt sagen!



Kommt ja auch hierher:
http://www-graphics.stanford.edu/~seander/bithacks.html

Da sind auch noch ein paar andere nette Varianten zu finden.


----------



## borromeus (10 Dezember 2010)

Ja, da haben ein paar bitgewixt.....
Mein Favorit ist jedoch nachwievor- leider finde ich den Beitrag nicht-
die Erkennung von mehr als einem Bit in einem Wort.....

ich glaube die meisten kennen das....


----------



## Thomas_v2.1 (11 Dezember 2010)

borromeus schrieb:


> Ja, da haben ein paar bitgewixt.....
> Mein Favorit ist jedoch nachwievor- leider finde ich den Beitrag nicht-
> die Erkennung von mehr als einem Bit in einem Wort.....
> 
> ich glaube die meisten kennen das....



Meinste den:
http://www.sps-forum.de/showpost.php?p=215197&postcount=8


----------



## borromeus (11 Dezember 2010)

Ja genau den!

Der ist wie Umberto Giordano's
http://www.youtube.com/watch?v=41Xndjshhw4

dem ist an diesem Tag eine wahrhaft wunderbare Melodie eingefallen....


----------



## borromeus (11 Dezember 2010)

Thomas_v2.1 schrieb:


> Meinste den:
> http://www.sps-forum.de/showpost.php?p=215197&postcount=8


 
Wenn Dir das eingefallen ist:
Kniefall!


----------



## PN/DP (11 Dezember 2010)

Thomas_v2.1 schrieb:


> Kommt ja auch hierher:
> http://www-graphics.stanford.edu/~seander/bithacks.html
> 
> Da sind auch noch ein paar andere nette Varianten zu finden.


Danke für den Link Thomas, interessante Seite. Die kannte ich noch nicht.

Da habe ich den uralten Algorithmus nicht her. Den habe ich ca. 1992 mal in C in einer Grafik-Bibliothek verwendet, weil der sehr gut vom Compiler in x86-Assembler umgesetzt wurde. Ich weiß aber echt nicht mehr, aus welchem Buch ich den damals hatte.
Es war dieser C-Code:

```
n = (n&0xF0)>>4 | (n&0x0F)<<4;
n = (n&0xCC)>>2 | (n&0x33)<<2;
n = (n&0xAA)>>1 | (n&0x55)<<1;
```
den habe ich nun einfach nur für 32-Bit S7-AWL erweitert.

Als ich meinen ersten Beitrag #7 (mit der Rotieren-Variante) geschrieben habe, wußte ich noch "da war doch mal was mit Bytes" - es fiel mir aber erst später wieder richtig ein. Und weil der Algorithmus wirklich gut ist, habe ich noch einen Beitrag rangehängt.

Man muß ja solche Algorithmen nicht selber erfinden - Hauptsache, sie fallen einem bei Bedarf wieder ein und man kann sie effizient in die jeweilige Programmiersprache übersetzen.

Harald


----------



## PN/DP (11 Dezember 2010)

Hier noch eine Variante aus der OSCAT (die brauchen dafür SCL) (aus der Plain Text Library 3.20, gekürzt):

```
FUNCTION REVERSE : BYTE
VAR_INPUT
	IN : BYTE;
END_VAR

(*
	version 1.1	18. feb 2008
	programmer 	hugo
	tested BY		tobias

This function reverses the bits of a byte so that after execution bit 7 is at bit 0 location and so forth.

*)

REVERSE := SHL(in,7) OR SHR(in,7) OR (ROR(in,3) AND 2#01000100) OR (ROL(in,3) AND 2#00100010)
	OR (SHL(in,1) AND 2#00010000) OR (SHR(in,1) AND 2#00001000);

END_FUNCTION
```

Harald


----------



## Klärmolch (11 Dezember 2010)

Wow,
ich bin platt was es da alles geht.

Gruß
Klaus


----------



## dalbi (11 Dezember 2010)

Hi,



PN/DP schrieb:


> Hier noch eine Variante aus der OSCAT (die brauchen dafür SCL) (aus der Plain Text Library 3.20, gekürzt)...



und warum (die brauchen dafür SCL)? Kannst Du das wohl nicht. 

Gruss Daniel


----------



## Toki0604 (11 Dezember 2010)

Hi allerseits,
habe diesen Thread mal verfolgt und bin echt fasziniert wie man mit einer solch vermeintlich einfachen Aufgabe umgehen kann. Das Beispiel mit dem Bitgewixe ist echt der Hammer. Habe es getestet und stundenlang von Real Exponent / Mantisse zerpflückt um zu verstehen warum das eigentlich funktioniert. Wer sich das ausgedacht hat der denkt nur noch in Bit+Byte....
Aber Hut ab, die Version merk ich mir !
Gruß
Toki


----------



## borromeus (11 Dezember 2010)

Meinst Du die "mehr als ein Bit im Word vorhanden"- Sache?


----------



## Toki0604 (11 Dezember 2010)

Ja genau, 2 Bit im Word True.
Hab echt gebraucht bis ich die "Bits" alle verstanden habe.


----------

