Forum: Mikrocontroller und Digitale Elektronik Assambler division 56bit/32bit


von Ingo (Gast)


Lesenswert?

Hallo liebes Forum,

Ich bin noch recht unerfahren, was assamblerprogrammierung angeht und 
habe zur Zeit ein Problem.
Ich möchte eine 56bit Zahl (Vorher durch multiplikation erhalten 
32bit*24bit)
ducht eine 32bit zahl teilen.
Mein ansatz bis jetzt: Man nehme das Tutorial (was ich echt klasse 
finde!) zum Thema Arithmetik mit 16 und 32bit- Dabei speziell division 
32bit/32bit
Habe die version 1.2 gewählt (Also erster Kasten ungerundet)
Die gerundete Form habe ich auch nicht verstanden... Also das urdiv32... 
Funktioniert das wirklich?
Naja ich habe halt die version udiv32 genommen und modifiziert.
Das ganze funzt auch für bestimmte Divident/divisor paarungen aber 
irgendwie nicht für alle. Denke mit lange suchen würde ich das Problem 
ergründen aber wenn hier jemand einen guten Lösungsansatz hätte wäre ich 
dankbar!! Brauche auch eigentlich den Rest nicht- also rounded wäre 
schon klasse- wenn nicht sogar besser, weil weniger rechenintensiv!?

Werde auch, wenn bis dahin noch keine Lösungsvorschläge ala hier haste 
Routine eingetrudelt sind mal meinen Ansatz posten.

Besten Dank im Vorraus!

Ingo

von spess53 (Gast)


Lesenswert?

Hi

>Ganz einfach: Du nimmst einen (bei dir ungenannten) 32-Bit Prozessor,
>der einen Divisionsbefehl hat. Der kann dann 64/32=32:32.

Ein AVR kann das auch. Allerdings wäre es mal interessant, wozu man das 
braucht.

MfG Spess

von TH (Gast)


Lesenswert?

Hallo Ingo,

wieso drehst Du die Operation nicht um?
Wenn Du - wie Du gesagt hast - zuerst die Multiplikation 32x24 = 56bit
durchführst und dann wieder eine 32bit Division durchführen möchtest,
dann kannst Du doch alles umdrehen:
Also zuerst die 32/32 Division und im Anschluss die 24bit 
Multiplikation.
Das geht aber nur dann, wenn Zähler>Nenner ist.

Zu Deinem 2. Problem: Nicht alle 32/32bit Paarungen funktionieren - 
könnte daran liegen, dass der Divisor größer ist als der Divident und 
dann das Ergebnis <1 wäre?


Gruß
TK

von Jim M. (turboj)


Lesenswert?

> Also zuerst die 32/32 Division und im Anschluss die 24bit
> Multiplikation.
> Das geht aber nur dann, wenn Zähler>Nenner ist.

Sorry TH, aber das geht nur wenn Zähler >> Nenner, also der Zähler sehr 
viel größer ist. In allen anderen Fällen verliert man deutlich an 
Genauigkeit. Dein Vorschlag geht eigentlich nur gut bei float oder 
double Werten.

von Purzel H. (hacky)


Lesenswert?

Wie man so eine Division macht... wie man's als Kind in der Schule 
gemacht hat. schriftliche Division. Eigentlich ist es sogar einfacher. 
Die Subtraktion geht oder nicht, und man bekommt eine Eins oder eine 
Null.

von Peter D. (peda)


Lesenswert?

Ingo schrieb:
> Das ganze funzt auch für bestimmte Divident/divisor paarungen aber
> irgendwie nicht für alle.

Dann hast Du einen Fehler gemacht.
Ich bin aber kein Hellseher, um mehr sagen zu können.

Und wenn Du Dich auf ein Beispiel beziehst, dann poste auch den Link 
darauf.


Peter

von Ingo (Gast)


Angehängte Dateien:

Lesenswert?

Hallo nochmal!
Also ersmal Danke für die rege Beteiligung!
@spess53: Benutze einen ATMEGA32 (hätte ich villeicht direkt 
dazugeschrieben...)

@TH: Also ich habe das problem dass ich die Rechnung ~0.2 (das ist der 
Knackpunkt) Setzt sich aus einer 0.01*0.000xxxxxx(32bit)*360*10000(mit 
angehängten nullen von den 10000 (nur ein Faktor um nach der Division 
mit gewünschter genauigkeit vor dem Komma zu bleiben) 24bit) als 
dividend und einer x.xxxxx(32bit)als divisor zusammen.

als Ergebnis möchte ich eine Zahl zwischen 7.3 und 7.8 mit einer 
genauigkeit von ~3Stellen nach dem Komma bekommen natürlich um die 3 
Zehnerpotenzen verschoben die 0.01 ist der Gewichtungsfaktor für eine 
einfache Filteroperation, die dann folgt.

Also denke ich, dass ich um die Reihenfolge der Rechenschritte nicht 
rumkomme.

@Jim Meba- exakt das problem ;-)

@kilo Oschi: Joo das habe ich im Prinzip verstanden und auch versucht 
umzusetzen. Aber irgendwo ist da ein Haken (have versucht das mit 
möglichst wenig lade und speichervorgängen umzusetzen...

@Peter Dannegger: Joo das ist mir durchaus bewusst...
Hier der link: http://www.mikrocontroller.net/articles/AVR_Arithmetik

habe dort den Algoritmus genutzt, der unter Division
                                            32bit/32bit  steht
und dort wie erwähnt udiv32

Habe jetzt auch  mal den mist angehängt, den ich verbockt habe- 
villeicht fällt da jemandem direkt was auf, was so nicht geht...
die routine soll, wenn sie denn läuft in ein anderes Programm eingefügt 
werden.

Soo hoffe Hilfe naht...


Ingo

von Ingo (Gast)


Lesenswert?

Ach und noch erwähnenswert:
Die Zahlen r26-r22 sowie r23-r26 sind nur als "Versuchszahlen" zu 
verstehen... (damit stimmt das Ergebnis auf jeden Fall net...)

von Peter D. (peda)


Lesenswert?

Ingo schrieb:
> Habe jetzt auch  mal den mist angehängt

Was soll denn der Code hinter "jump:" machen?
Ich verstehe das nicht.

Du must einfach nur hinter den Vergleich springen, also direkt zum 
Subtrahieren.
D.h. läuft Temp über, muß man immer subtrahieren.


Peter

von Ingo (Gast)


Lesenswert?

@Peter: Das problem siehst Du, wenn Du das Programm ohne den Jump sprung 
simulierst. Dann funktioniert der erste Deil der Division 
FFFFFF/CD3EE018 gut, aber dann laufen vor dem nächsten Divisionsschritt 
der register r27-r30 über, was zur folge hat, da es kein register r31 
gibt, der die 1 aufnimmt die Subtraktion nicht durchgeführt wird... Der 
vergleich r27-r30 und r23-r26 fällt dann negativ aus, obwohl er positiv 
sein sollte... (oder andersherum?)

Deshalb habe ich den jump schritt eingefügt, der dem ganzen dann eine 1 
vor r27-r30 setzt und eine 0 vor r23-r26 -> subtraktion wird dann 
ausgeführt und dann sollte das doch wieder hinhauen? Habe das so 
umständlich gemacht, weil ich zu wenige register zur verfügung habe... 
:-(

Oder ist das einfacher zu lösen?

von Ingo (Gast)


Lesenswert?

Naja wenn ich dann aber die übergelaufenen Register subtrahiere stimmt 
das ergebnis doch nicht?

das wird doch dann negativ

von Ingo (Gast)


Lesenswert?

Oder ist das ein imaginärer Fehler, der aus meinem Dezimaldenken heraus 
entsteht?

von Ingo (Gast)


Angehängte Dateien:

Lesenswert?

Danke Peter! Das war der Knackpunkt!
Habe fälschlicherweise übersehen, dass die Carry flag mit subtrahiert 
wird...

Anbei das die laufende Division 56bit/32bit mit Erklärungen falls jemand 
das gleiche Problem haben sollte.

Weise darauf hin,  dass das Grundgerüst aus dem exzellenten Tutorial ur 
Assambler-Programmierung entnommen ist- will mich ja nicht mit fremden 
Federn schmücken ;-).

Die Division selber spielt sich ausschließlich in der Interruptschleife 
ab das drum herum ist nur Beiwerk. Sollte man dies auch nutzen wollen 2 
Tips:

1.Schalter zum Interrupt auslösen ist problematisch wenn nicht 
hardwareentprellt (softwareentprellung nicht implementiert)

2. Wenn zur Übertragung über RS232 der normale COM port benutzt wird 
muss die Baudrate reduziert werden (für günstige Baudwerte Prozessor 
datenblatt lesen)

Funktion ohne Gewähr (habe bis jetzt nur 10 Wertepaare ausprobiert...)

Beste Grüße,
Ingo

von Wegstaben V. (wegstabenverbuchsler)


Lesenswert?

"Assambler"

Das gibt Augenkrebs!  Das Zeugs heißt "Assembler" und kommt vom 
englischen Wort "to assemble"

von Ingo (Gast)


Lesenswert?

Deshalb habe ich Luft- und Raumfahrttechnik studiert und nicht Deutsch 
oder Englisch... Rechtscheibung ist nicht so mein favorite...
im Englischen die AE-Schwäche satellite wird bei mir gern mal 
satallite...
(es lebe die Rechtschreibprüfung von Word, Open office writer oä!!!!)
im Deutschen Groß- und Kleinschreibung... Bestimmt auch schon 
aufgefallen!?
Und Hauptsache man verständigt sich- ne?!

Aber Danke für den Tipp- werde mich (villeicht) bessern!

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.