C Bitmanipulation über verschiedene Register

Folienkondensator

Neues Mitglied
28. Mai 2012
89
0
0
Sprachen
  1. ANSI C
  2. Assembler
Hallo

Ich hänge mal wider an einer warscheinlich ganz einfachen sache. :D

Ich habe drei Register (A,B und C)
Code:
Bit Zahl       87654321
Register A = 0b00000010
Register B = 0b00000110
Register C = egal

Wie schaffe ich es das Bit 2 von Register A mit Bit 2 von Register B zu XORn und diesen Wert in Register C auf Bit 8 abzulegen?
Gibz da ne einfache Möglichkeit ohne für jedes Bit eine Bitmaske anlegen zu müssen?

Gruß
Folienkondensator
 
Code:
MOV C, A
EOR C, B
ANDI C, 0b00000010
und danach schieben bzw Multiplizieren falls das mit MUL oder so zufällig(!) hier Sinn macht (C=R0 und 'ne 6 in irgend'nem anderen Register). Der Prozzi muß dann MUL natürlich auch können...

Wie sollen denn ohne Maske (ANDI) Bits ausgeblendet werden können?
In Deinem konkreten Beispiel kannst Du natürlich auch direkt nach dem EOR schieben, da das LSB überall 0 war (die anderen 1en wandern ja über das Carry ins Nirvana), aber das ist bei dem Beispiel nur zufällig so, oder?

Edit: Oder sollen die anderen Bits in C dabei unverändert bleiben?
Hmm da sollte sich doch eigentlich mit C oder T im SREG und ein paar SKIPs was machen lassen...
 
In C könnte es so aussehen ...
(ungetestet)
Code:
RegisterC &= ~(1<<7); // Bit 7 löschen
RegisterC |= ((((RegisterA & 2) ^ (RegisterB & 2)) << 6) & (1<<7));

Bit 0..6 von RegisterC werden nicht verändert.

Dirk :ciao:
 
Da er die Sprache nicht angegeben hat, hier nochmal ASM:
Code:
  BST A, 1
  BRTC null
  SBRC B, 1
  CLT
  RJMP ready
null:
  BST B, 1
ready:
  BLD C, 7

PS an Dirk: mit Bit2 meint er Bit1, da er mit Bit1 als LSB anfängt...

Auch hier sind natürlich die Bitnummern (1,7) und Register (A, B, C) festgelegt (zumindest zur Laufzeit)

Nachtrag: mein unkonventioneller Trick mit dem Port-Bit eines nicht verwendeten I/O-Beinchens (zB Reset) geht hier natürlich auch - da können dann beliebig viele Bits verXORrt werden...
(Port-Bit 0 setzen, fragliche Bits mit SBRC prüfen, und ggf das Port-Bit durch beschreiben des Pin-Bits toggeln, ZielBit erstmal 0 setzen (ANDI), und in Abhängigkeit des Portbits (SBIC) auf eins setzen (ORI)...
 
Hallo LotadaC,
PS an Dirk: mit Bit2 meint er Bit1, da er mit Bit1 als LSB anfängt...

ja ich weiß. Das mit &2 (0b00000010) maskiert Bit1 (wenn man 0..7 definiert).

Ich finde es besser, wenn man sich die Definition von 0..7 angewöhnt ... ist natürlich Geschmackssache :)

Hier noch ein bisschen kürzer (das mit &2 entfällt :eek:):

Code:
RegisterC &= ~(1<<7); // Bit 7 löschen
RegisterC |= (RegisterA ^ RegisterB)  << 6) & (1<<7));
 
|= bewirkt, daß nur gesetzte Bits nach C übernommen werden? Dann müssen aber die Zwischenergebnisse der Zeile (intern) in einem weiteren (4ten) Register zwischengespeichert werden, oder? Bis auf die Berücksichtigung der Bits 0..6 von C ist das dann quasi dasselbe wie bei meinem ersten Vorschlag, oder? Um die dann mit zu berücksichtigen, müßte ich eben dann auch erstmal Bit7 in C löschen (ANDI), statt C erstmal ein (4tes) Hilfsregister verwenden, und dieses dann mit C verANDen, oder?
Wäre dann dasselbe in den beiden Sprachen, oder?
 
|= bewirkt, daß nur gesetzte Bits nach C übernommen werden? Dann müssen aber die Zwischenergebnisse der Zeile (intern) in einem weiteren (4ten) Register zwischengespeichert werden, oder? Bis auf die Berücksichtigung der Bits 0..6 von C ist das dann quasi dasselbe wie bei meinem ersten Vorschlag, oder? Um die dann mit zu berücksichtigen, müßte ich eben dann auch erstmal Bit7 in C löschen (ANDI), statt C erstmal ein (4tes) Hilfsregister verwenden, und dieses dann mit C verANDen, oder?
Wäre dann dasselbe in den beiden Sprachen, oder?


Ja dein ersten Beispiel macht das selbe, es fehlt dann nur noch ein paarmal nach links shiften (nicht durch carry).

"|" steht in C für ODER.

A |= 1 ist ausgeschrieben A = A | 1. Das C Beispiel ist unabhängig vom Zielsystem, das Ergebnis ist das selbe als wenn es auf einen PIC, ARM oder sonst was läuft. Ob da irgendwas in einem Register zwischengespeichert wird, ist hier nicht so interessant, bzw. man weiß es normalerweise nicht. :) ... und das ist auch gut so :-D ;-)
 
Da wart ihr wider schneller als ich. trotzdem lass ich die Frage mal stehen ;)
Hallo

Danke Ihr beiden.
Ich hab eigentlich die Sprache C gemeint, aber gut dass ich es in ASM auch mal gesehen hab ;)

@Dirk:

Code:
RegisterC |= ((((RegisterA & 2) ^ (RegisterB & 2)) << 6) & (1<<7));

Das Bit "1" (Wie es ja eigentlich heißen sollte) von Register A und B werden ge XORt und in Bit "7" des Registers C geschrieben. ( Mit "<< 6" ) Ist das richtig?
Worfür benötigt man dann "&(1<<7)" ? Oder verstehe ich da was ganz falsch?

Gruß
 
Verwende am besten diese Version:

Code:
RegisterC &= ~(1<<7); // Bit 7 löschen
RegisterC |= ((RegisterA ^ RegisterB)  << 6) & (1<<7));

zunächst wird in RegisterC bit 7 gelöscht.
Dann wird RegisterA XOR RegisterB gebildet. Das Ergebnis wird 6 mal nach links geschoben. Das Ergebnisbit 1 ist nun auf Position Bit 7. das ganze wird dann mit 0b10000000 (= 1<<7) "verundet" (also alles gelöscht ausser Bit7)
Das Ergebnis wird dann mit RegisterC "verodert" :)

Meine Bitpositionen sind 7..0.
 
Hi

Ich zähle eigentlich auch von 0-7. Wie ich auf 8 gekommen bis weis ich auch nicht xD

Oke. Das hjab ich jetzt soweit kapiert.
Kann man bei deinem vorherigen Beispiel die Bits die ver "XORt" werden sollen bestimmen?
Ich wollte nämlich eigentlich die Checksumme von meinem LIN Projekt bilden.
Um die Checksumme für die ID bilden zu können muss ich die Bits 0,1,2, und 4 ver XORn.

Also:
ID Register = 0b00010101
Checksumme = ID-Bit0 xor ID-Bit1 xor ID-Bit2 xor ID-Bit4

Code:
	checksumme =0;
	checksumme = ((LIN_id & 0) ^ (LIN_id & 1));
	checksumme = ((checksumme & 0) ^ (LIN_id & 2));
	checksumme = ((checksumme & 0) ^ (LIN_id & 4));

So hatte ich mir das gedacht. Aber das funktioniert natürlich nicht so einfach xD
Gruß
 
Das könnte vielleicht so funktionieren ...

Code:
// immer alles auf Bit0 bezogen
checksumme = LIN_id ^ (LIN_id >> 1);        // Bit0 XOR Bit1
checksumme = checksumme ^ (LIN_id >> 2);     // XOR Bit2
checksumme = checksumme ^ (LIN_id >> 4));    // XOR Bit4

//Ergebnis ist in Bit0, alle anderen Bits haben irgendwelche Zustände

Dirk :ciao:
 
Hi

Hat super funktioniert. Danke! ;)

Ich hab mal der einfachkeit halber etwas versucht und bemerkt dass es auch mit dieser Schreibweise funktioniert:
Code:
	checksumme = ((LIN_id >> 0) ^ (LIN_id >> 1) ^ (LIN_id >> 2) ^ (LIN_id >> 4));

Gruß
Folienkondensator
 
Hat super funktioniert. Danke! ;)

Ich hab mal der einfachkeit halber etwas versucht und bemerkt dass es auch mit dieser Schreibweise funktioniert:
Code:
    checksumme = ((LIN_id >> 0) ^ (LIN_id >> 1) ^ (LIN_id >> 2) ^ (LIN_id >> 4));

:D Ja, einzeilig geht es auch. Ich wollte möglichst bei deinem vorgegebenen Beispiel bleiben, da ich dachte, es ist dann besser verständlicher. Der erzeugte Code ist wahrscheinlich in beiden Fällen sehr ähnlich.

Dirk :ciao:
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)