mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik zwei 16-Bitzahlen vergleichen


Autor: Stevko (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo an alle Forumsteilnehmer,

wie der Betreff schon aussagt möchte ich zwei 16-Bit große Zahlen
vergleichen. Ziel ist zu erkennen ob die zu vergleichende Zahl größer
oder kleiner ist. Programmiersprache ist Assembler.
Mit 2x cp (High/Low) kommt man nicht um die Runden. Ich habe zwar eine
Routine geschrieben durch da sind mir zu viele Vergleiche und Sprünge.
Irgendwo gabs mal eine ganz kurze Routine, doch die finde ich nicht
mehr.
Hat jemand einen Codeschnipsel oder kann mir einen Tipp geben um die
Sache abzukürzen.

Gruß
  Stevko

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ein cp ist nichts anderes als eine Subtraktion, bei der das Ergebnis
verworfen und nur die Flags gesetzt werden. Genauso, wie man
Subtraktionen unter Verwendung des Carry-Flags kaskadieren kann, kann
man auch die Vergleiche kaskadieren. Dazu gibt's bei AVR-Controllern
das cpc - compare with carry.

Autor: Gerhard (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

z.B.

         cp ZL, r18           ;
         cpc ZH, r19          ;
         brge PC+5            ;


Gruss Gerhard

Autor: Stevko (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Rolf,

der Tipp war gut. Da ich es nicht ausprobieren kann, bin auf der
Arbeit, hätte ich noch eine Frage. Kann ich nach dem Vegleich
erkennen/springen ob die Zahl größer oder kleiner ist?

.equ Vergleichzahl = 1234
;
;Wert laden
ldi R16,Low(2222)
ldi R17,High(2222)
;
;zuerst Low vergleichen
cp R16,Low(Vergleichzahl)
;jetzt High
cpc R17,High(Vergleichzahl)
breq Zahl_ist_gleich
 oder
brlo Zahl_ist_kleiner
 sonst
rjmp Zahl_ist_größer


Gruß
  Stevko

Autor: Stevko (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ups, da habe ich wohl zu lange für den Text gebraucht! Naja auf der
Arbeit sollte man wenigstens ab und zu mal was tun.
Danke auch an Gerhard, also sollte mein Beispiel funktionieren.

Gruß
  Stevko

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Kann ich nach dem Vegleich erkennen/springen ob die Zahl
> größer oder kleiner ist?

Du kannst einfach mehrere branch-Befehle nacheinander ausführen, da sie
selbst die Flags nicht ändern.

> ;zuerst Low vergleichen
> cp R16,Low(Vergleichzahl)
> ;jetzt High
> cpc R17,High(Vergleichzahl)
> breq Zahl_ist_gleich
>  oder
> brlo Zahl_ist_kleiner
>  sonst
> rjmp Zahl_ist_größer

Einfach "oder" und "sonst" weglassen ;-)



Gruß
  Stevko

Autor: Simon Küppers (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Äh, wenn du 2 16-Bit Werte hast, und die vergleichen willst, brauchst du
doch nur 2x CP. Low Byte und High Byte vergleichen und fertig. Wenn die
Zahl gleich war, müssen beide CPs TRUE gewesen sein.

Autor: Stevko (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Rolf:
Das mit den mehreren Branch habe ich mir nicht "getraut". Aber wenn
es geht kürzt es ganz schön ab. sehr gut!

@Simon:
Ich möcht auch erkennen ob eine Zahl größer/kleiner ist.

Gruß
  Stevko

Autor: A.K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Stevko: Was meinst Du wohl was Gerhard oben geschrieben hat?

Autor: Stevko (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@A.K.
Was meinst Du mit Deiner Aussage? Hast Du alle! Threads gelesen?

Stevko

Autor: Andi K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich denke mal, das hat er!
Siehe 3. Beitrag von oben:

         cp ZL, r18           ;
         cpc ZH, r19          ;
         brge PC+5            ;Verzweige wenn größer oder gleich
                              ;(Greather or Equal)

Auf die Art und Weise, wie es Gerhard vorschlug, mußt Du den zu
vergleichenden Wert vorher in die Register r18 (low) und r19 (high)
laden.
Möchte man das allerdings nicht machen weil man sowieso mit einer
festen Konstannte vergleicht, geht es auch mit cpi und cpc wobei man
für cpc keinen "Immediate"-Wert angeben kann, sondern nur Register:

;zuerst Low vergleichen
 ldi R18,High(Vergleichzahl) ;Temporär high-Byte in r18 für cpc
 CPI R16,Low(Vergleichzahl)
;jetzt High
 CPC R17,r18
 breq Zahl_ist_gleich
 brlo Zahl_ist_kleiner
 BRSH Zahl_ist_größer_oder_gleich ;(Same or Higher)

MfG
Andi

Autor: Andi K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ach ja, bei kleiner als, LOwer (LO) oder less then (LT), und bei größer
oder gleich, Same or Higher (SH) oder Greater or Equal (GE), mußt Du
aufpassen, welche Du für welchen Zweck benutzt.
LO und SH ist ohne Vorzeichen, also ohne negative Zahlen für den
Bereich von 0 bis 255 bei 8 Bit und LT und GE ist mit Vorzeichen für
einen Bereich von -128 bis 128 bei 8 Bit.

MfG
Andi

Autor: Arno H. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe dazu eine Verständnisfrage, mein Assemblerwissen ist noch auf
dem Level Z80 hi.
Wenn ich 2  16Bit Zahlen vergleichen sollte, würde ich zuerst das
Highbyte vergleichen, entweder mit compare oder durch Subtraktion. Bei
negativem Ergebnis (Flag ?)ist die eine Zahl kleiner, bleibt ein Rest,
ist sie größer und nur wenn das Ergebnis 0 (Flag ?) ist, muss ich das
Lowbyte überhaupt vergleichen.
Oder ist das so nicht praktikabel?
Arno

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Code ist dann halt länger und umständlicher und verbraucht mehr
Flash. Er ist bei Ungleichheit des High-Byte zwar um einen Taktzyklus
schneller, aber dafür bei Gleichheit langsamer.

Autor: Arno H. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Meiner Meinung nach muss ich doch eh zuerst das Highbyte vergleichen,
weil das Lowbyte erst dann zum Ergebnis beiträgt, wenn das Highbyte
gleich ist. Deswegen kann ich nicht nachvollziehen, warum ich das
Lowbyte zuerst vergleichen soll.
Die Codelänge und die Ausführungszeit hängen doch in erster Linie wohl
davon ab, wie oft die Gleichheit im Verhältnis zu einem ungleichen
Ergebnis erwartet wird, oder?

Arno

Autor: Peter Dannegger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Witz ist, CPC bzw. SBC werten das Z- und das C-Flag der vorherigen
Operation aus.

Du sparst also einige Sprungbefehle ein, wenn Du erst alle Bytes
vergleichst und hinterher springst.

Bei 32Bit- oder 64Bit-Zahlen wird das noch besser.


Peter

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.