Hallo ich hab da ne frage und es wäre super wenn mir jemand weiterhelfen könnte. wie kehrt man ein Register um? (LSB 1 wid MSB 2 und MSB 1 wird LSB 2) z.B 1101 0010 0100 1011 (ich meine nicht invertieren!!!!) Danke für jede Hilfe mgf
Das wird hier immer wieder mal gefragt. Suche mal hier im Forum "Bit reihenfolge umdrehen"
Bitweise nach links schieben und über Carry nach rechts in das Zielregister schieben.
Soll es zügig gehen und stehen 256 Byte Festspeicher dafür zur Verfügung, bietet sich ein Table-Lookup in eine Tabelle mit "rückwärts bestückten" Bits an.
In avr-gcc gibt's dafür ein Built-in, siehe am Ende der Seite: http://gcc.gnu.org/onlinedocs/gcc-4.7.2/gcc/AVR-Built_002din-Functions.html
1 | char rev (char bits) |
2 | {
|
3 | return __builtin_avr_insert_bits (0x01234567, bits, 0); |
4 | }
|
Wird compiliert zu:
1 | rev: |
2 | lsl r24 |
3 | adc r24,__zero_reg__ |
4 | mov __tmp_reg__,r24 |
5 | bst r0,1 |
6 | bld r24,7 |
7 | bst r0,2 |
8 | bld r24,6 |
9 | bst r0,3 |
10 | bld r24,5 |
11 | bst r0,5 |
12 | bld r24,3 |
13 | bst r0,6 |
14 | bld r24,2 |
15 | bst r0,7 |
16 | bld r24,1 |
17 | ret |
Hallo, da es bei fast allen Prozessoren keinen Befehl dafür gibt, braucht man 3 Register , 2 zum Schieben und 1 zum Zählen. Die Schleife erfordert dann 16 Schiebe- und 8 Zähl/Sprungbefehle, kürzer gehts nicht. Man kann natürlich die 16 Schiebebefehle hintereinanderschreiben und spart damit die Sprünge, nur wird dadurch das Programm länger. Gruss Reinhard
Hi >da es bei fast allen Prozessoren keinen Befehl dafür gibt, braucht man 3 >Register , 2 zum Schieben und 1 zum Zählen. Nö. Ein zusätzliches Register reicht. Das Prinzip stammt hier aus dem Forum. Allerdings weiß ich nicht mehr genau von wem (PeDa,KHB oder ....)
1 | ;**************************************************************************************** |
2 | ;* |
3 | ;* mirror_fast 26 Takte (mit call/ret) / 36 Byte |
4 | ;* |
5 | ;* Spiegeln r16 |
6 | ;* |
7 | ;**************************************************************************************** |
8 | |
9 | .if use_mirror_fast |
10 | |
11 | mirror_fast: push r17 |
12 | swap r16 |
13 | mov r17,r16 |
14 | |
15 | lsr r16 |
16 | lsr r16 |
17 | lsl r17 |
18 | lsl r17 |
19 | andi r16,$33 |
20 | andi r17,$CC |
21 | |
22 | or r16,r17 |
23 | mov r17,r16 |
24 | |
25 | lsr r16 |
26 | lsl r17 |
27 | andi r16,$55 |
28 | andi r17,$AA |
29 | or r16,r17 |
30 | pop r17 |
31 | ret |
32 | |
33 | .endif |
MfG Spess
Dieses Prinzip gibts auch in breit. Aufwand log(#Bits): http://graphics.stanford.edu/~seander/bithacks.html#BitReverseObvious Prozessoren mit Barrelshifter tun sich da leichter. Die formal (in C) kürzeste 8-Bit Variante ist wohl: b = (b * 0x0202020202ULL & 0x010884422010ULL) % 1023; Geht zwar auch auf AVR (bei GCC), aber...
Klaus 2m5 schrieb: > Bitweise nach links schieben und über Carry nach rechts in das > Zielregister schieben. So sieht das aus! Und zwar gegenseitig. Dann ist kein weiteres Register notwendig. Also so: ,---------v [<<<<<<<<][>>>>>>>>] ^---------' [01234567][89ABCDEF] [1234567F][089ABCDE] [234567FE][1089ABCD] [34567FED][21089ABC] [4567FEDC][321089AB] [567FEDCB][4321089A] [67FEDCBA][54321089] [7FEDCBA9][65432108] [FEDCBA98][76543210] Gruß Jobst
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.