PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : 16 bit Wert vergleichen?



pacer_one
01.12.2007, 21:13
Hallo,

kann mir jemand sagen wie ich am schnellsten zwei 16-bit Werte miteinander vergleichen kann?

Hintergrund:
Ich habe mir als Schleife einen 16-Bit Zähler mit R24/R25 aufgebaut, kann aber nicht vergleichen um die Schleife bei Erreichen eines bestimmten Zählerstandes zu verlassen

Grüße, JK

vklaffehn
01.12.2007, 21:24
moin!
hmm, damals zu C64'er Zeiten habe ich 16 Bit Zähler immer rückwärts gegen null laufen lassen, dann muß man am Ende 'nur' schauen, ob beide Bytes 0 sind, am besten erst das Highbyte testen, wenn das nicht null ist, kann man die Prüfung des Lowbytes eh gleich weglassen.
MfG Volker

pacer_one
01.12.2007, 21:43
mein Problem ist, dass ich die Ergebnisse beider Vergleiche und-verknüpfen muss.

vklaffehn
01.12.2007, 21:46
Moin!
Achso, hmm, müßte doch aber im Prinzip trotzdem gehen, ein Byte vergleichen, wenn gleich, dann 2. Byte vergleiche, wenn auch gleich -> fertig....
leider habe ich bisher noch keinen AVR in Assembler programmiert, daher weiß ich nicht inwieweit man mit Hilfe irgendwelcher Flags Register vergleicht.... Evtl. jeweils die Bytes voneinander abziehen und bei Zero-Flag ist es fertig? So hab ich das damals gemacht.....

MfG Volker

pacer_one
01.12.2007, 22:02
wenn ich zwei Werte miteinander vergleiche und diese sind gleich, wird das Z-Flag gesetzt. nur Leider kann ich das Z-flag nicht speichern zumindest wüsste ich jetzt nicht wie?!

Weitere Frage: wäre es nicht sinnvoller zwei der drei 16-Bit Register für einen Vergleich zu nehmen?

izaseba
01.12.2007, 22:05
:-k Was soll den Verglichen werden r24/r25 mit 2 anderen Registern, oder mit einer Konstante ?

Wenn 2 andere Register ist es ja einfach:


cp r24,r2 ;r2 ist Low Register Deiner 2 Zahl
cpc r25,r3 ; r3 ist High Register Deiner 2 Zahl

Je nachdem werden jetzt entsprechende Flags im SREG gesetzt und Du kannst
nach Lust und Laune mit breq brne brmi brge usw. verzweigen.

Oder verstehe ich Dein Problem jetzt nicht ?

Gruß Sebastian

EDIT:


wäre es nicht sinnvoller zwei der drei 16-Bit Register für einen Vergleich zu nehmen?


Welche 3 16-Bit Register meinst Du ?

pacer_one
01.12.2007, 22:34
Doch, hast du schon verstanden ;-)
Die Lösung ist zwar easy, ich wäre aber nicht von allein drauf gekommen.

danke

ich meine die x/y/z-Register. Ich habe mit den Registern bis jetzt noch nicht gearbeitet, weiß also nicht ob mit einem Befehl die Inhalte vergleichen kann

izaseba
01.12.2007, 22:48
ich meine die x/y/z-Register. Ich habe mit den Registern bis jetzt noch nicht gearbeitet, weiß also nicht ob mit einem Befehl die Inhalte vergleichen kann


Ach die meinst Du...
Dann füge ich noch x/y/z-Register Paare hinzu,
damit keiner meint, es gibt 16 Bit Register auf dem avr...

Ich meine man kann nicht mit einem Befehl vergleichen, man fängt immer mit dem niedrigsten Byte(LOW) an mit cp und arbeitet sich langsam Richtung HIGH mit cpc durch.
Alternativ kan man natürlich mit dem HIGH anfangen, wie vklaffehn schon vorgeschlagen hat, wenn die nicht gleich sind braucht man nicht weiter zu vergleichen...

Am sonsten wünsche ich noch einen erfolgreichen Programmierabend ;-)

Gruß Sebastian

pacer_one
01.12.2007, 22:52
was ich im Moment nicht verstehe, ich subtrahiere Register B von Register A und ziehe zusätzlich noch das Z-Flag ab. Also wird gesprungen wenn Register B+1=A ist

izaseba
01.12.2007, 23:27
Also wird gesprungen wenn Register B+1=A ist


:-k Du mußt die zwei Operationen als eine Einheit sehen.
was da im Carry steht ist nicht 1 sondern der Überlauf der 9. Bit sozusagen, der nicht mehr passt.
Der muß im High Byte mit abgezogen werden und hier steht der ja nicht mehr für 1 sondern für 256
Schau mal hier (http://www.izaseba.roboterbastler.de/index.php?popup=Tutorial&section=Lektion9)
habe ich versucht das zu erklären...
Sonst, hast Du avr Studio ?
Schreib Dir mal ein paar Zeilen Code wo sowas gemacht wird, setze verschiedene Werte in die Register rein und schaue, was da alles mit SREG passiert...
So Sachen, wie 200 von 5 abziehen usw.

Viel Spaß

Gruß Sebastian

Edit

und ziehe zusätzlich noch das Z-Flag ab

Nein nicht Z -> Zero sondern C -> Carry

Besserwessi
02.12.2007, 13:30
Die Befehle CP und CPC sind ähnlich wie dir Subtraktion mit SUB und SBC, nur das Ergebnis nicht ausgegeben wird. Das Carry Flag ist extra für den Überlauf vom low zum high Byte da.

thewulf00
03.12.2007, 09:02
Also ich würds so machen:


vergleich:
cp r24, 0x35
brne nicht_gleich
cp r25, 0x35
brne nicht_gleich
gleich:
was_auch_immer...
ret oder rjmp
nicht_gleich:
was_auch_immer...
Damit ist in 4-6 CPU--Zyklen der Vergleich abgeschlossen. Die beiden 0x35-Zahlen sind Deine Konstanten, die den Vergleichswert darstellen sollen.

wkrug
03.12.2007, 12:32
@thewulf00
Bei abfragen auf gleiche Zählerstände geht das so.
Bei größer, kleiner Abfragen wirds dann komplizierter.
Übrigens cp geht nicht mit einer Konstanten. Müsste der Befehl dann nicht cpi heissen ?

Also
ldi r16,low(adr)
ldi r17,high(adr)
cp xl,r16
cpc xh,r17
brxyz oder was auch immer

find ich einfacher. Wobei r16 und r17 natürlich die Vergleichswerte enthalten müssen.
r16 und r17 würd ich verwenden, weil mit denen LDI Befehle gehen.
Wenn die Datenquelle das RAM ist, gehen natürlich auch die Register unter r16.

thewulf00
03.12.2007, 14:45
Du hast völlig Recht, es muss CPI heißen. Das wäre der Punkt, wo ich beim Complieren noch mal drüber gucken müsste. :-)


Und ein größer/kleiner ist nicht nötig, siehe Aufgabenstellung:

Ich habe mir als Schleife einen 16-Bit Zähler mit R24/R25 aufgebaut, kann aber nicht vergleichen um die Schleife bei Erreichen eines bestimmten Zählerstandes zu verlassen

pacer_one
07.12.2007, 22:03
Dank der zahlreichen Tipps hab ich es inzwischen hinbekommen. In der Woche habe ich leider nur nicht immer die Zeit dran zu arbeiten.