www.mikrocontroller.net

Forum: Compiler & IDEs Bitshift Operationen in C


Autor: Pete (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Μαtthias W. (matthias) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi
*reg = *reg & 0xE0000007UL | zuSetzenderWert & ~0xE0000007UL;

Matthias

Autor: Pete (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke schonmal, aber kannst du mir das Vorgehen kurz erklären?

Autor: Μαtthias W. (matthias) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Pete (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: Pete (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Bob (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Pete (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Pete (Gast)
Datum:

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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Frank M. (ukw) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Μαtthias W. (matthias) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.