Betrag

Moderator: Rockford

Antworten
Benutzeravatar
Dr. Irata
Beiträge: 974
Registriert: 24.08.2021 14:40
Has thanked: 126 times
Been thanked: 291 times
Kontaktdaten:

Betrag

Beitrag 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?

Benutzeravatar
Dr. Irata
Beiträge: 974
Registriert: 24.08.2021 14:40
Has thanked: 126 times
Been thanked: 291 times
Kontaktdaten:

Re: Betrag

Beitrag von Dr. Irata »

aktuell würde ich es so machen:

Code: Alles auswählen

		sec
		lda a
		sbc b
		bpl @+
		sec
		lda b
		sbc a
@		sta c


Benutzeravatar
DjayBee
Beiträge: 722
Registriert: 17.08.2021 04:02
Has thanked: 452 times
Been thanked: 214 times
Kontaktdaten:

Re: Betrag

Beitrag von DjayBee »

So sollte es kürzer und schneller gehen:

Code: Alles auswählen

	sec
		lda a
		sbc b
		bpl @+
		sbc #0
		eor #$ff
@		sta c

Benutzeravatar
Dr. Irata
Beiträge: 974
Registriert: 24.08.2021 14:40
Has thanked: 126 times
Been thanked: 291 times
Kontaktdaten:

Re: Betrag

Beitrag von Dr. Irata »

sehr nice...

Benutzeravatar
Dr. Irata
Beiträge: 974
Registriert: 24.08.2021 14:40
Has thanked: 126 times
Been thanked: 291 times
Kontaktdaten:

Re: Betrag

Beitrag 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!

Benutzeravatar
DjayBee
Beiträge: 722
Registriert: 17.08.2021 04:02
Has thanked: 452 times
Been thanked: 214 times
Kontaktdaten:

Re: Betrag

Beitrag 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.

Code: Alles auswählen

		sec
		lda a
		sbc b
		bpl @+
		clc
		sbc #0
		eor #$ff
@		sta c

Benutzeravatar
Dr. Irata
Beiträge: 974
Registriert: 24.08.2021 14:40
Has thanked: 126 times
Been thanked: 291 times
Kontaktdaten:

Re: Betrag

Beitrag 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!

Erhard
Beiträge: 639
Registriert: 04.11.2021 15:52
Has thanked: 59 times
Been thanked: 151 times
Kontaktdaten:

Betrag

Beitrag von Erhard »

Nach meinem Kenntnisstand sind alle Verzweigungsbefehle in der Sprungweite limitiert.
Just because you're paranoid don't mean they're not after you ...

(Quelle: Nirvana)

Benutzeravatar
Dr. Irata
Beiträge: 974
Registriert: 24.08.2021 14:40
Has thanked: 126 times
Been thanked: 291 times
Kontaktdaten:

Re: Betrag

Beitrag 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.

Benutzeravatar
Mathy
Beiträge: 1246
Registriert: 18.06.2021 11:13
Wohnort: Heerlen, NL
Has thanked: 519 times
Been thanked: 283 times
Kontaktdaten:

Re: Betrag

Beitrag 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
Wer oder was hat denn da geblitzt?

Benutzeravatar
Dr. Irata
Beiträge: 974
Registriert: 24.08.2021 14:40
Has thanked: 126 times
Been thanked: 291 times
Kontaktdaten:

Re: Betrag

Beitrag 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:

Code: Alles auswählen

		sec
		lda a
		sbc b
		bcs @+
		sbc #0
		eor #$ff
@		sta c
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.

Benutzeravatar
Dr. Irata
Beiträge: 974
Registriert: 24.08.2021 14:40
Has thanked: 126 times
Been thanked: 291 times
Kontaktdaten:

Re: Betrag

Beitrag 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.

Erhard
Beiträge: 639
Registriert: 04.11.2021 15:52
Has thanked: 59 times
Been thanked: 151 times
Kontaktdaten:

Betrag

Beitrag 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
Just because you're paranoid don't mean they're not after you ...

(Quelle: Nirvana)

Antworten

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast