Forum: Compiler & IDEs Bitmanipulation mit variablen


von Michael B. (gm8816)


Lesenswert?

Hallo,
ich habe zwei Variablen. Die erste Variable soll das zu manipulierende 
Byte enthalten und die zweite soll die Bitnummer des zu manipulierenden 
Bits enthalten. Wie mache ich das jetzt in C.
Normalerweise mache ich es immer so: out |= (1<<0); Anstelle der 0 soll 
jetzt eine Variable stehen die dann die Werte 0..7 enthalten kann. In 
assembler habe ich so eine routine mal geschrieben aber vielleicht gibt 
es in C sowas schon integriert.

von yalu (Gast)


Lesenswert?

> Normalerweise mache ich es immer so: out |= (1<<0); Anstelle der 0
> soll jetzt eine Variable stehen die dann die Werte 0..7 enthalten
> kann.

Dann schreib die Variable doch einfach anstelle der 0 hin. Oder wo ist
das Problem?

von STK500-Besitzer (Gast)


Lesenswert?

unsigned char a,b,y;

Setzen:
y = a | (1<<b);

Löschen:

y = a & ~(1<<b);


Ich vermute, dass man mit XOR auch noch was basteln könnte...

von Michael B. (gm8816)


Lesenswert?

Danmke erstmal für die Antworten. Das hat soweit funktioniert.

von Philipp B. (philipp_burch)


Lesenswert?

Der GCC (Zumindest bei WinAVR) kennt _BV(), ist ein Makro für genau 
diese Funktion:
1
PORTA |= _BV(PB2);

von Günter R. (galileo14)


Lesenswert?

STK500-Besitzer wrote:
> unsigned char a,b,y;
>
> Löschen:
>
> y = a & ~(1<<b);
>

Habt ihr euch mal den Kommentar im avr-libc Reference Manual zu diesem 
Thema angesehen? Dort (in Version 1.4.3 auf S. 197) gibt es das Kapitel 
7.3.21 "Why does the compiler compile an 8-bit operation that uses 
bitwise operators into a 16-bit operation in assembly?"

Dort wird (mindestens) empfohlen, daß man einen Cast setzt:

y = a & (unsigned char)~(1<<b);

Ich mache es mal so, mal anders, bemerke aber keinen Unterschied 
(funktioniert in beiden Fällen). Kann jemand dazu mal Stellung nehmen? 
Ist der Cast wirklich notwendig?

von yalu (Gast)


Lesenswert?

> ... bemerke aber keinen Unterschied (funktioniert in beiden Fällen).

Ich auch nicht. Der Compiler (avr-gcc 4.2.2) erzeugt einen
16-Bit-Shift und ein 8-Bit-And, egal ob mit oder ohne Cast. Der
16-Bit-Shift bleibt auch dann, wenn man die 1 in (unsigned char)
castet.

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.