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);
}