hmmm...
was heisst denn elegent?
Elegant und korrekt als Inline Asm:
Bei Inline-Assembler ist unbedingt darauf zu achten, daß der Effekt auf die Maschine dem Compiler korrekt mitgeteilt wird!Code:static inline unsigned char swap_2_4_asm (unsigned char a) { unsigned char b; asm volatile ("bst %[a],2" "\n\t" "bld %[b],4" "\n\t" "bst %[a],4" "\n\t" "bld %[b],2" : [b] "=&r" (b) : [a] "r" (a), "0" (a)); return b; } uint8_t foo_asm (uint8_t b) { return swap_2_4_asm (b); }
Das Ergebnis nur an einem Beispiel testen genügt nicht. Wenn sich das Programm ändert und der Compiler etwas anderen Code erzeugt, fliegen einem die obigen asm-Schnippsel um die Ohren (bzw. der AVR macht es).
In C kann man es elegant über Bitfelder lösen, was leider von GCC momentan noch -- gelinde gesagt -- suboptimal übersetzt wird:
Code:typedef union { struct { unsigned b0 :1; unsigned b1 :1; unsigned b2 :1; unsigned b3 :1; unsigned b4 :1; unsigned b5 :1; unsigned b6 :1; unsigned b7 :1; }; unsigned char val; } bit8_t; static inline unsigned char swap_2_4_c (unsigned char a) { bit8_t xa = {.val = a}; bit8_t xb = {.val = a}; xb.b4 = xa.b2; xb.b2 = xa.b4; return xb.val; } uint8_t foo_c (uint8_t b) { return swap_2_4_c (b); }







Zitieren

Lesezeichen