Seite 1 von 1
Betrag
Verfasst: 04.11.2022 10:29
von Dr. Irata
Aktuell suche ich eine kurze schnelle Routine für den Betrag einer Differenz in Assembler:
Beispiel:
c = |a-b|
also bei a=10 und b=6 ---> c=4
und bei a=6 und b=10 ---> c=4
wer hat gute Ideen?
Re: Betrag
Verfasst: 04.11.2022 10:37
von Dr. Irata
aktuell würde ich es so machen:
Re: Betrag
Verfasst: 04.11.2022 12:17
von DjayBee
So sollte es kürzer und schneller gehen:
Re: Betrag
Verfasst: 04.11.2022 12:43
von Dr. Irata
sehr nice...
Re: Betrag
Verfasst: 04.11.2022 13:36
von Dr. Irata
kleine Ergänzung noch nach einem Hinweis von Janko:
Die Verzweigung mittels BPL ist ja auf +- 128 limitiert, daher sollte man besser statt BPL BCS nehmen!
Re: Betrag
Verfasst: 04.11.2022 17:09
von DjayBee
Da muss ich Janko widersprechen.
Das funktioniert nur wenn du immer zwei positive Zahlen voneinenander abziehst.
Wenn du nach einer Subtraktion von einem negativen Wert ausgehst, dann geht dein Wertebereich für ein Byte zwingend von -128 bis +127 und das Bit 7 ist dein Vorzeichenbit.
Genau darauf hebt das BPL ab. Wenn Bit 7 gesetzt ist, gilt die Zahl als negativ und BPL verzweigt nicht.
Ich habe aber gerade noch festgestellt, dass das Carry gelöscht werden muss wenn das auch für negative Zahlen funktionieren soll.
Nach der Subtraktion von negativen Zahlen ist das Carry immer gesetzt und somit führt das SBC #0 zum falschen Ergebnis.
Re: Betrag
Verfasst: 05.11.2022 00:33
von Dr. Irata
da hast du im Prinzip natürlich Recht, aber im Prinzip ging es mir ja primär um die Subtraktion zweier positiver Zahlen im Raum von 0-255, um quasi eine Range zu definieren: Also z.B. zwischen 250 und 10 - als Ergebnis 240 oder zwischen 10 und 250 - als Ergebnis auch 240 - also nur den positiven Abstand dieser zwei Zahlen!
Betrag
Verfasst: 07.11.2022 07:55
von Erhard
Nach meinem Kenntnisstand sind alle Verzweigungsbefehle in der Sprungweite limitiert.
Re: Betrag
Verfasst: 07.11.2022 11:40
von Dr. Irata
Hallo Erhard,
ja das stimmt!
In diesem Fall jetzt ging es aber nicht um die Sprungreichweite der Verzweigungsbefehle, sondern um die Tatsache, daß einige Befehle das Bit 7 als Vorzeichen benutzen - also Minus- oder Pluszahl. In diesem Fall hat die entsprechende Zahl die Wertigkeit -127 bis +127 statt 0 bis 255.
Wenn man nun zum Beispiel 10-240 berechnen will würde man ja mathematisch zunächst -230 erhalten. In unserem Beispiel möchte ich aber den Betrag haben, als Ergebnis soll dann am Ende also +230 stehen. Das brauche ich zum Beispiel, wenn ich nur den Abstand zwischen zwei Zahlen bestimmen will. Und der Abstand zwischen 10 und 240 ist immer 230.
Die reine Subtraktion im 8-Bit-System von 240 und 10 beträgt 230. Dieses Ergebnis ist richtig und erwünscht.
Die Subtraktion von 10 und 240 beträgt aber 25, invertiert man nun durch EOR das Ergebnis (im Grunde subtrahiert man nochmals 255 und 25) erhält man auch 230. Die Routine spuckt also immer den Betrag von a-b aus.
Der Befehl BPL wird aber zu einem Fehler führen, da er Bit 7 als Vorzeichen interpretiert.
Die Zahl 240 würde ein BPL-Befehl nicht als 240 interpretieren, sondern als -112 und die Zahl 10 normal als +10.
Eine durchgeführte Subtraktion von 240-10 führt nun zu dem Ergebnis 230, der Befehl BPL erkennt hier aber die Zahl
- 102 eine Subtraktion von 10-240 führt ja wie oben geschrieben zu 25, BPL sollte jetzt eigentlich nicht verzweigen, da das Ergebnis eigentlich falsch ist und invertiert werden soll, für BPL ist der Wert aber mit 25 positiv und verzweigt in unserem Beispiel und macht die Invertierung mit 255 nicht - was nun aber zu einem falschen Ergebnis führt.
Re: Betrag
Verfasst: 07.11.2022 14:50
von Mathy
.
Hallo Peter
Kann man nicht zuerst beide Zahlen vergleichen um raus zu finden welche von beiden die Größte ist und dann die Kleinste von der Grössten abziehen?
Tschüß
Mathy
Re: Betrag
Verfasst: 07.11.2022 15:22
von Dr. Irata
Hallo Mathy,
letztlich machen wir das ja. Die Frage ist immer, was ist der schnellste und beste Code.
Am Ende ist dies wohl der beste Code:
Hier wird ja zunächst a-b gerechnet. Ist a>b kommt direkt der Sprung zu @ und das Ergebnis wird in c gespeichert ... fertig. Falls a<b erfolgt ja ein Overflow, d.h. Carry wird gesetzt und geht von 1 auf 0 und die Verzweigung wird nicht ausgelöst. Das Ergebnis bei a<b wird nur mit 255 ($ff) invertiert und am Ende bekommt man den Betrag des Ergebnisses.
Re: Betrag
Verfasst: 07.11.2022 17:05
von Dr. Irata
... vielleicht noch ein kleiner genereller Hinweis zur Subtraktion:
Der Befehl sbc bedeutet ja Subtraktion mit Carry.
Das bedeutet, bei der Subtraktion schaut der Befehl nach, ob das Carry 0 oder 1 ist. In diesem Fall interpretiert der Befehl bei Carry 1, daß nichts "geborgt" werden musste und also kein Overflow Stattgefunden hat - in unserem Fall also a>b - wenn man nun aber vor der Subtraktion kein SEC gesetzt hat, dann kann ja das Carry bei 0 schon sein und der Befehl sbc geht von der Situation a<B aus - in diesem Fall wird eins zu viel abgezogen. Das System muss also vor jeder Subtraktion mit SEC beginnen. Das Carry wird also mit SEC auf 1 gesetzt,.
Eine Subtraktion a-b (bei a>b) ändert nicht am Carry (bleibt bei 1) und der Branchbefehl bcs wird ausgelöst und verzweigt entsprechend zur Sprungmarke (bei uns @).
Bei a-b (a<B) erkennt der Befehl, daß er eine "Eins" borgen muss und setzt hier das Carry auf Null, die Verzweigung findet nicht statt und der Befehl mit der Invertierung kann ausgeführt werden.
Betrag
Verfasst: 07.11.2022 18:18
von Erhard
Hi,
ich bezog mich auf diese Berkung:
Prodehl hat geschrieben: ↑04.11.2022 13:36
Die Verzweigung mittels BPL ist ja auf +- 128 limitiert, daher sollte man besser statt BPL BCS nehmen!
Die klingt, als ob für BCS die Sprungweitenbeschränkung nicht gelten würde.
Ist ja jetzt geklärt.
Viele Grüße
Erhard