Forum: Compiler & IDEs Bitshift Operationen in C


von Pete (Gast)


Lesenswert?

Hi,

mal ne kurze Frage, will ein Register setzen, aber ohne die obersten 3 
Bit und die untersten 3 Bit zu verändern, wie löse ich das am 
geschicktesten.

Danke schonmal

von Μαtthias W. (matthias) Benutzerseite


Lesenswert?

Hi
1
*reg = *reg & 0xE0000007UL | zuSetzenderWert & ~0xE0000007UL;

Matthias

von Pete (Gast)


Lesenswert?

Danke schonmal, aber kannst du mir das Vorgehen kurz erklären?

von Μαtthias W. (matthias) Benutzerseite


Lesenswert?

Hi

schreibs mal in mehrere Zeilen und vergewissere dich nochmal das du die 
Bedeutung und die Priorität der C Operatoren kennst. Dann kannst du dir 
das selber erklären.

Matthias

von Karl H. (kbuchegg)


Lesenswert?

Pete schrieb:
> Danke schonmal, aber kannst du mir das Vorgehen kurz erklären?

Du führst die beiden Werte zusammen


    Registerwert                       zu setzender Wert

        |                                      |
        v                                      v

     alles ausser den obersten 3        die obersten 3 und die
     und den untersten 3 Bits auf 0     untersten 3 Bits auf 0 setzen
     setzen


in den beiden Teilen hast du jeweils die Bits auf 0 forciert, die vom 
jeweiligen Partner kommen werden. Du kannst daher die beiden Teile jetzt 
ganz einfach zusammenodern, ohne dass es zu unerwünschten Interaktionen 
der beiden Teile kommen wird.


       |                                       |
       +-------------    Odern   --------------+
                           |
                           |
                           v
                        Ergebnis


Was du im Grunde gemacht hast:
Du hast ein rotes Papier mit einer Maske mit einem rechteckigen 
Ausschnitt abgedeckt. Malst du mit einer Walze "Löschfarbe" drüber, so 
wird nur der Teil innerhalb des Ausschnitts gelöscht, der rote Rand 
bleibt erhalten.

Dann nimmst du eine Folie mit rotem Muster und legst die genau 
gegenteilige Maske drauf und malst wieder mit Löschfarbe drüber. Der 
Rand der Folie wird gelöscht.

Legst du dann die Folie auf das Papier, dann passen die Ränder perfekt 
aneinenander. AUssen rum ist das Original vom Papier, innen drinnen ist 
das Muster von der Folie und nirgends kommt es zu Überlappungen der 
beiden Bereiche.

von Pete (Gast)


Lesenswert?

Oh man, ich kann das Register doch einfach nur verodern mit 0b00011000 
dann bleiben die linken und die rechten 3 Bits umberührt...

Danke für die schnelle Hilfe!

von Karl H. (kbuchegg)


Lesenswert?

Pete schrieb:
> Oh man, ich kann das Register doch einfach nur verodern mit 0b00011000
> dann bleiben die linken und die rechten 3 Bits umberührt...

wenn es immer 0b00011000, das du dann reinsetzen musst, kannst du das 
machen. Aber diese Zusage hast du ja am Anfang nicht gemacht. Da war 
noch von einem beliebigen Wert die Rede.

von Falk B. (falk)


Lesenswert?


von Pete (Gast)


Lesenswert?

*reg = *reg & 0xE0000007UL | zuSetzenderWert & ~0xE0000007UL;

Aber wenn ich mein reg (z.B. reg=0b10100110) mit 0b11100111 verunde, 
veränder ich doch den Wert meines Registers, oder sehe ich das falsch?

von Bob (Gast)


Lesenswert?

Pete schrieb:
> Aber wenn ich mein reg (z.B. reg=0b10100110) mit 0b11100111 verunde,
> veränder ich doch den Wert meines Registers, oder sehe ich das falsch?

Du veränderst damit nicht das Register, es wird ein Zwischenergebnis 
berechnet.
Das Register ändert sich erst ganz am Ende, bei der Zuweisung.

Außerdem: Das Ver-UND-Ern löscht nur die Bits, die laut deiner 
Aufgabenstellung auch gelöscht+überschrieben werden müssen.

von Pete (Gast)


Lesenswert?

Irgendwie verstehe ich das noch nicht ganz...

Ich habe ein Register ausgelesen, z.B. reg=0b10100110, in diesem 
Register will ich das die oberen drei und die unteren drei sich nicht 
verändern, also nur 4 und 5. Das ganze soll dann so aussehen 
reg=0b10110110, dieses Byte wird dann wieder in das Register 
geschrieben. Nach oben beschriebener Formel, verändere ich mein reg 
durch die UND Funktion, so das es nicht mehr dem Ursprungsbyte 
entspricht.

von Pete (Gast)


Lesenswert?

Weiterhin weiss ich auch nicht wie mein reg aussieht, es kann sich von 
mal zu mal ändern...

von Karl H. (kbuchegg)


Lesenswert?

Pete schrieb:

> Ich habe ein Register ausgelesen, z.B. reg=0b10100110, in diesem
> Register will ich das die oberen drei und die unteren drei sich nicht
> verändern, also nur 4 und 5.

3 und 4. Wir beginnen bei 0 zu zählen.

OK.
Da du zunächst nicht weißt, was in die Bits 3 und 4 rein soll, setzt du 
sie erst mal gezielt auf 0. Denn dann kannst du im Falle eines Falles 
immer noch eine 1 rein-odern

Aus
   0b10100110

machst du also


   0b101xx110

wobei die x die Positionen andeuten, die auf 0 gezwungen werden.

> Das ganze soll dann so aussehen
> reg=0b10110110,

also willst du an die Stelle xx die Bits 10 einsetzen.

> dieses Byte wird dann wieder in das Register
> geschrieben.

ganz zum Schluss, wenn alles fertig ist. Ja.

> Nach oben beschriebener Formel, verändere ich mein reg
> durch die UND Funktion,

Du veränderst doch nicht das Register nur weil du dir den Wert von dort 
holst und diesen Wert mit etwas verundest. Das Register hat nach wie vor 
denselben Wert. Du manipulierst die Kopie des Wertes, die du erhältst, 
indem du das Register ausliest.

In

  j = i + 5 + 8;

verändert sich doch i auch nicht, nur weil du 5 zum Wert von i 
dazuzählst und mit diesem neuen Zwischenergebnis weitere Operationen 
machst.

> so das es nicht mehr dem Ursprungsbyte
> entspricht.

Wenn du dann das Ergebnis der ganzen Manipulationen wieder an das 
Register zuweist, dann hat es natürlich einen anderen Wert. Nämlich den, 
der sich durch deine Manipulationen ergeben hat.

Das hier

 *reg = *reg & 0xE0000007UL | zuSetzenderWert & ~0xE0000007UL;
        |                                                   |
        |                                                   |
        +---------------------------------------------------+

ist 1 arithmetischer Ausdruck, so wie in

   j = 3 * i + 5 * k;

rechts vom = auch nur 1 arithmetischer Ausdruck steht. Der wird 
ausgewertet und was immer sich daraus ergibt wird an i (bei dir an *reg) 
zugewiesen.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Pete schrieb:
> Weiterhin weiss ich auch nicht wie mein reg aussieht, es kann sich von
> mal zu mal ändern...

Du hast noch nichtmals verraten, wie breit Dein Register ist. Matthias 
war mit seiner Antwort nämlich etwas gemein ;-)

Gruß,

Frank

von Μαtthias W. (matthias) Benutzerseite


Lesenswert?

Hi

warum war ich gemein? Er hat nicht angegeben wie breit seine Register 
sind und damit bin ich mal von einer Maschine ausgegangen auf der ich 
normalerweise so unterwegs bin.

Matthias

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.