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
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
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
> 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.
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.
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
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
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...)
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
@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?
Naja wenn ich dann aber die übergelaufenen Register subtrahiere stimmt das ergebnis doch nicht? das wird doch dann negativ
Oder ist das ein imaginärer Fehler, der aus meinem Dezimaldenken heraus entsteht?
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
"Assambler" Das gibt Augenkrebs! Das Zeugs heißt "Assembler" und kommt vom englischen Wort "to assemble"
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.