Forum: Mikrocontroller und Digitale Elektronik Parität eines Registers Rausfinden (Assembler)


von Mike D. (hero2992)


Lesenswert?

hallo...

Ich bin dabei ein kleines Programm zu schreiben indem ich die Parität 
eines Registers herausfinden möchte und später mit dem T-Flag anzeigen 
möchte...

T = 0 heisst Parität ist gerade
T = 1 heisst Parität ist ungerade

Ich habe das Programm bereits soweit das ich die Anzahl Einsen (im 
Binärcode) in einem Register angezeigt bekomme... Nun muss ich nur mehr 
rausfinden ob die Zahl gerade oder ungerade ist... wie kann ich das 
machen...

MFG Mike

von Tim S. (maxxie)


Lesenswert?

Schreib dir mal auf Papier auf, wie ungerade Zahlen 1,3,5,7... in binär 
aussehen. Du wirst schnell herausfinden, wie du eine ungerade Zahl 
erkennst.

von Hc Z. (mizch)


Lesenswert?

Wenn Du die Anzahl der Einsen hast, zeigt das unterste Bit eine gerade 
(0) oder ungerade (1) Zahl an.

Es geht aber einfacher: 
http://www.nongnu.org/avr-libc/user-manual/group__util__parity.html

von Frank S. (Firma: HSCS) (linuxerr)


Lesenswert?

Es wäre sinnvoll, wenn du den Controllertyp angegeben hättest, denn 
viele haben einen speziellen Befehl, um die Parität zu bestimmen. Oft 
ist es so, dass ein Paritätsbit bei Arithmetik oder Logikbefehlen 
automatisch gesetzt wird.
Wenn du von einer Binärzahl wissen wills, ob sie gerade oder ungerade 
ist, dann musst du nur die letzte Bitstelle testen. Ist diese 1, dann 
ist die zahl ungerade, ist sie 0, dann ist die zahl gerade. Testen 
kannst du das zb mit rechts-Schiebebefehlen, die das niederwertige Bit 
in ein Flag(Carry z.B.) schieben. Du kannst auch eine and-Maske 0x01 auf 
die Zahl legen und testen, ob das ergebnis 0 ist.

von Mike D. (hero2992)


Lesenswert?

Danka für die schnelle Antwocht... sehr dumm von mir... da hätte ich 
auch selbst drauf kommen können... ich arbeite mit einem Atmega 8  und 
soviel ich weiss gibt es hier kein Paritäts bit / Flag oä...

Vielen Dank... ich schreibs jetzt schnell um dann poste ich noch das 
programm...

von Mike D. (hero2992)


Lesenswert?

Hier mein programm...

.include "m8def.inc"
.org 0x0000

CLR R16      ;lösche R16
LDI R17,0x09  ;Lade 0x09in R17 = Schleife
Immer:

Dec R17
BRNE Weiter    ;wenn Schleife nicht a ende ist gehe zu Weiter
ROR R16      ;Rotiere R16 nach Rechts Bit 0 in Carry
BRCC Aus    ;Wenn carry = 0 gehe zu Aus
SET        ; Sonst setze T Flag
Aus: Rjmp Aus  ;Endlosschleife

Weiter:
Rol R20      ;Rotiere R20 Nach Links mit Carry
BRCS Paritaet  ;Wenn carry = 1 gehe zu Paritaet

Rjmp Immer    ;Gehe zu Immer

Paritaet:

Inc R16      ; Addiere 1 zu R16 gibt anzahl Einsen an

Rjmp Immer    ;Gehezu Immer

von spess53 (Gast)


Lesenswert?

Hi

Hier mein Programm:
1
      ldi r18,0b11111110   ; deine Zahl
2
      clr r17              
3
      ldi r16,8            ; acht mal
4
5
aaa:  eor r17,r18
6
      lsr r18
7
      dec r16
8
      brne aaa
9
      bst r17,0            ; Parität nach T

MfG Spess

von (prx) A. K. (prx)


Lesenswert?

@Mike: Einfacher wird es, wenn man das Bit ins Carry rausschiebt und 
anschliessend schlicht ebendieses Carry zur Summe addiert (ADC r,0).

von Hc Z. (mizch)


Lesenswert?

Unter obigem Link hättest Du ein spaghetticode-freies Assemblerprogramm 
gefunden, das kürzer und schneller ist ...

von Mike D. (hero2992)


Lesenswert?

Hallo Spess danke für das Kurze Programm... WOW Ich bin 
begeistert...programmiere noch nicht sehr lange aber so ein kurtzes 
Programm hätte ich nie hin bekommen...Zumindest habe ich es 
verstanden...auch wenn ich was länger brauchte...hehe

>Unter obigem Link hättest Du ein spaghetticode-freies Assemblerprogramm
>gefunden, das kürzer und schneller ist ...

Ja ich habe mir den Link angesehen... wurde jedoch nicht schlau draus...


Jetzt habe ich noch eine Frage... ich möchte mein programm erweitern un 
zum beispiel die anzahl an Low pegel von 2 Ports (ATMega8) in ein 
register schreiben... jedoch kann ich hier nicht mehr mit Rol oder ROR 
arbeiten... we kann ich hier intelligent vorgehen?

von spess53 (Gast)


Lesenswert?

Hi

>we kann ich hier intelligent vorgehen?

Da hilft wirklich nur Zählen. Einfach beide Ports (PinX) in zwei 
Register einlesen.

Mal so aus dem Stehgreif:

     in r16,PinA
     in r17,PinB
     ldi r18,16
     clr r19

aaa: sbrc r16,0
     inc r19
     lsr r17
     ror r16
     dec r18
     brne aaa

MfG Spess

von Mike D. (hero2992)


Lesenswert?

Noch ne frage zu deinem Programm (von Spess) aus dem Stehgreif.. (ne 
kleine sache die ich nicht verstehe... wie kümmerst du dich denn hier um 
das Register R17? dieses Wird da gar nicht bearbeitet oder übersehe ich 
hier etwas? und wieso gebrauchst du für das R16 den ROR Befehl Carry 
wird doch gar nicht gebraucht oder?

Hoffe du hast verständnis für meine fragen... hehe...

von (prx) A. K. (prx)


Lesenswert?

LSR/ROR bildet zusammen einen 16-Bit Schiebebefehl.

von (prx) A. K. (prx)


Lesenswert?

@Spess: Du zählst die Einsen, nicht die Nullen.

von (prx) A. K. (prx)


Lesenswert?

Fixere Variante:

     in r16,PinA
     in r17,PinB
     ldi r18,16
     ldi r19,16

aaa: lsr r17
     ror r16
     sbci r19,0
     dec r18
     brne aaa

von spess53 (Gast)


Lesenswert?

Hi

>wie kümmerst du dich denn hier um das Register R17?

Du wolltest doch die Leitungen von 2 Ports?

>wie kümmerst du dich denn hier um das Register R17?

Doch, mit 'in r17,PinB'

> und wieso gebrauchst du für das R16 den ROR Befehl Carry wird doch gar...

'lsr r17' schiebt Bit0 von r17 ins Carryflag. 'ror r16' schiebt das 
Carry-Flag nach Bit7 von r16. Das Ganze entspricht einem '16Bit-lsr'.

Ich habe gerade gesehen, das du die Nullen zählen willst. Dann muss es 
heissen:

aaa: sbrs r16,0

MfG Spess

von Andreas F. (aferber)


Lesenswert?

A. K. schrieb:
> @Spess: Du zählst die Einsen, nicht die Nullen.

Ja und? Bei gerader Gesamt-Bitzahl sind entweder beide gerade oder beide 
ungerade, hat auf die Parity also keinen Einfluss.

Andreas

von spess53 (Gast)


Lesenswert?

Hi

>Fixere Variante:

Stimmt.

MfG Spess

von (prx) A. K. (prx)


Lesenswert?

Andreas Ferber schrieb:

> Ja und? Bei gerader Gesamt-Bitzahl sind entweder beide gerade oder beide
> ungerade, hat auf die Parity also keinen Einfluss.

Es ging in diesem Fall bereits um die Anzahl Null-Bits, nicht mehr um 
die Parität.

von Andreas F. (aferber)


Lesenswert?

A. K. schrieb:
> Es ging in diesem Fall bereits um die Anzahl Null-Bits, nicht mehr um
> die Parität.

OK. Ist trotzdem einfacher, die Einsen zu zählen. Dann am Ende eben noch 
einmal von 16 abziehen, dann passt es wieder.

Andreas

von (prx) A. K. (prx)


Lesenswert?

Andreas Ferber schrieb:

> OK. Ist trotzdem einfacher, die Einsen zu zählen. Dann am Ende eben noch
> einmal von 16 abziehen, dann passt es wieder.

Nö. Spess' Version ist da wie gezeigt neutral (SBRS/SBRC) und meine ist 
bei Nullen einfacher. Einsen braucht ein NEG hintendrein.

von Mike D. (hero2992)


Lesenswert?

Hallo Ich hatte bereits zu beginn den SBRC in SBRS umgewandelt...

Trotzem Einen grossen Dank An alle...

von Mike D. (hero2992)


Lesenswert?

Hallo hier bin ich wieder... Heute wollte ich einem freund dieses 
Programm erklären... doch ich bekam es nicht hin... ich verstehe die 
einzelnen schritte doch die logik dahinter und den weg ein solches 
programm zu schreiben konnte auch ich nicht ganz verstehen...

nun wollte ich mal fragen ob mir niemand (wenn auch nur kurz) erklären 
könnte wie man dadrauf kommt...

das es fonktioniert sehe ich ja..^^

ich habe mir dann ein Blatt genommen und jeden schritt aufgeschrieben... 
nur die Logik fehlte mir... warum es so ist...


spess53 schrieb:
> Hi
>
> Hier mein Programm:
>
>
1
>       ldi r18,0b11111110   ; deine Zahl
2
>       clr r17
3
>       ldi r16,8            ; acht mal
4
> 
5
> aaa:  eor r17,r18
6
>       lsr r18
7
>       dec r16
8
>       brne aaa
9
>       bst r17,0            ; Parität nach T
10
>
>
> MfG Spess

Hoffe ihr könnt mir nochmals helfen...

gruss Mike

von spess53 (Gast)


Lesenswert?

Hi

>Heute wollte ich einem freund dieses Programm erklären...

Freund oder Lehrer?

Du solltest dir mal die Logiktabelle für Ex-Oder (eor) zu Gemüte führen.

Es interessiert nur das Bit0 von r17 und r18. Eine 1 in Bit0 von r18 
invertiert Bit0 von r17. Eine Null nicht. Also ist Bit0 (von r17) nach 
einer geradzahligen Anzahl von Invertierungen wieder Null, nach einer 
ungeraden Anzahl von Invertierungen Eins. Ganz einfach.

MfG Spess

von Mike D. (hero2992)


Lesenswert?

nein einem Freund... aber ich dachte das ganze Register 17 würde 
eventuell noch was anzeigen...ich bin jedoch immer noch davon 
begeistert... danke spess

von spess53 (Gast)


Lesenswert?

Hi

>...ich bin jedoch immer noch davon begeistert...

Ich auch. War eine ganz spontane Idee.

>aber ich dachte das ganze Register 17 würde eventuell noch was anzeigen

r17 wird zwar jedes mal komplett verändert, aber nur Bit0 ist 
interessant.

MfG Spess

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.