MIPS Parität bestimmen

Gast #5685898
Lesenswert?

Hallo,
Ich arbeite mich schon seit Stunden durch unzählige Foren durch, auf der 
Suche nach einer Hilfe. Mein Problem ist, dass ich die Parität einer 
Binärzahl in einem Register bestimmen möchte.
Mein Ansatz: In einem weiteren Register die aktuelle Parität (während 
der Berechnung speichern) und diese immer mit der letzen Ziffer vom 
ersten Register XORen.
Mit srl kann ich die Ziffern natürlich verschieben, wie komme ich 
allerdings an die letze Ziffer? Und wie kann ich eine Schleife 
schreiben, die das eleganter löst?

Bitte nicht einfach Programmcode posten, eine Erklärung zur Verständnis 
würde mir wesentlich mehr helfen. Danke im Voraus!
#5686317
Lesenswert?

Du kennst die Anzahl der Bits pro Register, also kennst du die Anzahl 
der nötigen Schiebevorgänge, bis alle Bits aus dem Register raus sind.

Es spielt keine Rolle, wieviele und welche Bits in deinem Register 
gesetzt sind, denn dein Algorithmus soll ja nicht die Parität der 
unteren N Bits berechnen, sondern die des ganzen Registers.

Also nimm dir drei Register:
- ein Register mit deinem Wert
- ein Register mit der Startparität
- ein Register mit dem Zählwert (vermutlich 31 oder 32).

Den Rest solltest du allein hinkriegen. :-)

Im Übrigen ist der Begriff "Ziffer" ungünstig gewählt. In deinem 
Register steht eine Binärzahl, und deren Ziffern nennt man Bits.
Gast #5686521
Lesenswert?

Danke für die zahlreichen Antworten!

S. R. schrieb:
> Du kennst die Anzahl der Bits pro Register, also kennst du die Anzahl
> der nötigen Schiebevorgänge, bis alle Bits aus dem Register raus sind.

Leider verstehe ich noch nicht, was ich genau mit dem Schieben machen 
soll. Beispiel:
Mein Wert beträgt 111, meine Startparität (sinnvollerweise) 0 und mein 
Zählwert 32. Ich würde dann gerne das letzte Bit des Wertes jeweils mit 
dem aktuellen Parität XORen und das Ergebnis in der Parität speichern. 
Den Wert dann um ein Bit nach rechts verschieben und das Ganze Zählwert 
mal wiederholen. Aber mit XOR wird ja jedes Bit geXORt, nicht nur das 
letzte. Also:
111 XOR 000 = 111
011 XOR 111 = 100
001 XOR 100 = 101

Da habe ich noch nicht raus, wie sich das realisieren lässt. Für Hilfe 
wäre ich dankbar!
Gast #5686552
Lesenswert?

Ich möchte in meinem Register, das die Parität angibt, gerne eine 0 oder 
eine 1 stehen haben. Dafür nutze ich bitweise den and Befehl für Parität 
(zum Beispiel 101) und 1 (=> 001), was dann 001 = 1 ergibt
Gast #5686584
Lesenswert?

Mensch Marti, jetzt bin ich stinkesauer! Ich habe dir doch den Link 
gepostet:
1
  v &= v - 1; // clear the least significant bit set
Gib das im Windows Taschenrachner ein wenn du die Bits sehen willst.

Zum Zählen der Bits machste einfach 'ne Schleife drum:
1
unsigned int v;       // word value to compute the parity of
2
bool parity = false;  // parity will be the parity of v
3

4
while (v)
5
{
6
  parity = !parity;
7
  v = v & (v - 1);
8
}

Dann gehst du zu der Seite hier und gibts den Code ein: 
https://godbolt.org/z/hwzmsB

Raus kommt tolles asm für deine Hausaufgabe:
1
parity(unsigned int):
2
  move $2,$0
3
$L3:
4
  beq $4,$0,$L5
5
  addiu $3,$4,-1
6

7
  xori $2,$2,0x1
8
  b $L3
9
  and $4,$4,$3
10

11
$L5:
12
  j $31
13
  nop

bingo!
Gast #5686596
Lesenswert?

Mensch BitSchieber, ich bin zwar dankbar für jeden, der mir helfen will, 
aber einfach nur eine richtige Lösung bringt mich ja wohl nicht weiter.
a) habe ich den Ehrgeiz zu verstehen, was ich mit meinem Namen abgebe 
und b) möchte ich meine Klausur später auch erfolgreich schreiben können
Gast #5686600
Lesenswert?

Versuchen das Rad neu zu erfinden ist oft nicht der beste Ansatz. Nimm 
doch einfach eine gute, bekannte Lösung (wie angegeben zum Beispiel), 
klatsch die in eine .c Datei, mach ein paar printfs an interessanten 
Stellen dazu und lass es laufen. Dann geh mit dem Bleistift durch das 
Programm und die vergleich mit der printf Ausgabe.

Ich glaube so kannst du in so einem Fall mehr lernen. Wenn du dann eine 
eigene, andere, bessere, Lösung abgeben möchtest, dann kannst du ja ein 
bisschen dran rumschrauben, sobald du es verstanden hast.
#5686602
Lesenswert?

Marti schrieb:
> Jetzt habe ich es glaube ich verstanden!
> Ich mache genau das wie in meinem letzten
> Post beschrieben und am Ende nutze ich
> andi $Parität, $Parität, 1. Richtig?

Solange du dir nicht die Eingangsdaten überschreibst, ja.
Ich kann kein MIPS-Assembler. :-)

Du kannst auch vier Register benutzen:
- A: Eingangswert
- B: temporäres Register
- C: Ergebnisregister
- D: Zählregister
1
B <= A AND 1
2
C <= C XOR B
3
A <= A SHR 1
4
und wieder von vorne (32x)
Gast #5687304
Lesenswert?

Mein Programm funktioniert soweit, ich bin mit der Lösung auch 
zufrieden. Falls noch jemand auf diesen Post stößt, hier mein Code:
1
.data
2
wert: .word 100
3
pari: .word 0
4

5
.text
6
.globl main
7
main:
8
lw $2, wert
9
lw $3, pari
10
li $4, 32
11

12
loop:
13
xor $3, $2, $3
14
srl $2, $2, $1
15
subi $4, $4, 1
16
bgt $4, $0, loop
17

18
andi $3, $3, 1
19
sw $3, pari

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren