Mahlzeit, ich benötige für eine Zeitkritische Geschichte eine Routine (ASM) womit ich auf einem ATmega1281 eine 16 Bit Variable durch eine Konstante (in diesem Fall 180) teilen kann. Hat jemand vielleicht etwas Code-Geschnippsel da? Ich glaub mein Mathe-Verständnis reicht dafür nicht aus um durch 180 zu teilen (und nur Addition, Sub. sowie Div und Mul mit Potenzen von 2 (shift)) zu verwenden. Ich hoffe jemand kann mir auf die Sprünge helfen :) Viele Grüsse
du kannst die 16 Bit Zahl einfach mit 364 multiplizieren und dann die obersten 16 Bits des Ergebnisses verwenden. x / 180 = (x * (65536 / 180)) / 65536 = (x * 364,088888...) >> 16 Je nach geforderter Präzision geht das am Schnellsten.
Oder du rechnest: Ergebnis=Zahl/256+Zahl/512-Zahl/4096 usw. Geht komplett ohne Multiplikation oder Division, nur durch Schieben. Wird aber vermutlich langsamer sein als die Lösung von Kai.
Hmmm, rein von der Idee her schon gut... Nur dann brauch ich wieder 32 Bit Variablen, da wird dadd ganze natürlich wieder sehr Komplex :(... Zumal wenn man nur die High-bytes nimmt, dass das ergebnis wieder nur 8 Bit ist... und 65535 / 180 = 364 ;) Viele Grüsse
So wie Kai es beschrieben hat geht es. Oder als universelle und schnelle Division in Assembler: http://elm-chan.org/docs/avrlib/div16.txt http://elm-chan.org/docs/avrlib/div08.txt http://elm-chan.org/docs/avrlib/div24.txt http://elm-chan.org/docs/avrlib/div32.txt Jochen Müller
Ihr seit top... Jörgs Variante braucht grad mal 20 Takte.... Sowas nenn ich doch mal Klasse ;D Bascom hätte dafür mal locker über das 10-Fache gebraucht.... Vielen Dank an euch!!!!
Dad * 364 kann man noch vereinfachen, indem man *182 nimmt und dann nach links schiebt... (16-Bit-Wert in X, Ergebnis in r22/r23)
1 | clr r22 |
2 | ldi r23,182 |
3 | mul XL,r23 |
4 | movw r20,r0 |
5 | mul XH,r23 |
6 | add r21,r0 |
7 | adc r22,r1 |
8 | clr r23 |
9 | lsl r20 |
10 | rol r21 |
11 | rol r22 |
12 | rol r23 |
13 | sbrc r21,7 |
14 | subi r22,0xff |
15 | brne label |
16 | subi r23,0xff |
17 | label: |
auf die Schnelle, ohne Garantie... Gruß Jörg
sorry, mir ist noch eingefallen, dass ich mir die Benutzung von r16 sparen kann, deshalb die schnelle Löschung des vorherigen Codes. Gruß Jörg
und prompt ist noch ein kleiner Fehler drin, ich hoffe, jetzt stimmts:
1 | clr r22 |
2 | ldi r23,182 |
3 | mul XL,r23 |
4 | movw r20,r0 |
5 | mul XH,r23 |
6 | add r21,r0 |
7 | adc r22,r1 |
8 | clr r23 |
9 | lsl r20 |
10 | rol r21 |
11 | rol r22 |
12 | rol r23 |
13 | ldi r20,0x80 |
14 | add r21,r20 |
15 | clr r20 |
16 | adc r22,r20 |
17 | adc r23,r20 |
Gruß Jörg
Auch nur auf die Schnelle: lsl r20 kann raus, da der Wert nicht mehr gebraucht wird. Die Rundung am Ende kann durch eine Addition mit 91 am Anfang ersetzt werden - das spart u.U. noch mal ein Bisschen. Je nach Anforderung kann die auch komplett entfallen. Ansonsten lässt sich da vermutlich nicht mehr viel dran machen.
>und prompt ist noch ein kleiner Fehler drin, ich hoffe, jetzt stimmts:
Dann les' ich jetzt nochmal :)
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.