Forum: Mikrocontroller und Digitale Elektronik MIPS Parität bestimmen


von Marti (Gast)


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!

: Verschoben durch User
von S. R. (svenska)


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.

von Stefan (Gast)


Lesenswert?

Hallo,

sag mal welches Register in welcher CPU.

viele Prozessoren haben ein "Paritätsbit im Statusregister" und man muss 
nur irgendwie erzwingen dass es gesetzt wird!!!

Gruss

von (prx) A. K. (prx)


Lesenswert?

Im Titel steht MIPS. Und in der Lehre ist das vmtl immer 32-Bit. Spar 
dir die Mühe, nach einem Statusregister zu suchen, es gibt keines.

NB: Ein Parity Bit im Statusregister ist ausserhalb der Welt der 
Intel-Architekturen nicht sonderlich häufig.

: Bearbeitet durch User
von Joerg W. (joergwolfram)


Lesenswert?

Wenn es schnell gehen soll, könnte man sich eine Paritäts-Tabelle mit 
256 Einträgen für je 8 Bits machen und die errechneten Tabellenwerte für 
alle 4 Bytes xor oder addieren.

von BitSchieber (Gast)


Lesenswert?

Hallo Marti,

leg dir am besten für diese Webseite ein Lesezeichen an:
https://graphics.stanford.edu/~seander/bithacks.html

Dort sind 5 Varianten erklärt.

Auch für andere Rechnungen mit Bits gibt es auf dieser Seite wunderbare 
Hilfe!

Freundliche Grüße

Ein Informatiker

von S. R. (svenska)


Lesenswert?

Ich gehe mal stark davon aus, dass es sich hierbei um eine Hausaufgabe 
handelt. In einer MIPS-Assembler-Prüfungsklausur wird dir dein Prof was 
husten, wenn du da so rangehst. :-)

von Marti (Gast)


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!

von bome (Gast)


Lesenswert?

Marti schrieb:
> Aber mit XOR wird ja jedes Bit geXORt, nicht nur das letzte.

Du wertest nur Bit0 des Ergebnisses
aus und wirfst die anderen weg.

von Marti (Gast)


Lesenswert?

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?

von bome (Gast)


Lesenswert?

Marti schrieb:
> Richtig?

Deinen Code versteh ich nicht.
Bit0 des Ergebnisses ist die Parität

von Marti (Gast)


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

von BitSchieber (Gast)


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!

von Marti (Gast)


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

von BitSchieber (Gast)


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.

von S. R. (svenska)


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)

von Marti (Gast)


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

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.