Hallo ich suche Möglichkeiten, in AVR-Assembler durch 200 zu teilen, und zwar möglichst effezient. Also fast ohne Speicherplatzverbrauch. Gruss Robert
Hi >ich suche Möglichkeiten, in AVR-Assembler durch 200 zu teilen, und zwar >möglichst effezient. Also fast ohne Speicherplatzverbrauch. Kommt darauf an , was du durch 200 teilen willst. 8,16 32,64... Bit? MfG Spess
Hi Ein paar Links: http://www.avr-asm-tutorial.net/avr_de/rechnen/div8d.html http://www.atmel.com/dyn/resources/prod_documents/doc0936.pdf http://www.atmel.com/dyn/resources/prod_documents/AVR200.zip Beitrag "DIVISION 32 BIT / 32BIT Beispiel (Assembler) ATmega8" MfG Spess
Von Atmel gibts feine Appnotes :) Da ist auch ne 32bit/32bit Division aufgeführt. Einmal auf Code Größe und einmal auf Leufzeit optimiert. Die kannst du ja direkt nehmen oder weiter optimieren. Bei dir würde ja auch 32bit/8bit reichen :)
Servus, kann man nicht einfach 3x Shiften? also um 7, um 6 und um 3? Oder führt das nicht zum Ziel? gruß~
heldvomfeld schrieb: > Servus, kann man nicht einfach 3x Shiften? also um 7, um 6 und um 3? > Oder führt das nicht zum Ziel? > > gruß~ nein.
Hallo, im Beispiel unten, die 10 in 200 ändern. Lässt sich auch leicht auf 24 oder 32 Bit erweitern.
1 | ;-------------------------------------------------------------------------------- |
2 | ; 16Bit Division durch 8Bit Konstante. In diesem Fall 10. |
3 | ; Übergaberegister & Ergebniss in temp2/temp3 (low/high), Rest = temp1 |
4 | ;-------------------------------------------------------------------------------- |
5 | div: ldi temp4,16 ;16* schieben |
6 | clr temp1 ;Rest =0 |
7 | dv1: lsl temp2 |
8 | rol temp3 |
9 | rol temp1 |
10 | cpi temp1,10 ;Solange Bits in temp1 (Rest) schieben bis >= 10 |
11 | brcs dv2 ;Wenn der Rest <10 ist, das 0-Bit in temp2 (LSL, oben) stehen lassen |
12 | inc temp2 ;Ansonsten Bit0 setzen und 10 vom Rest abziehen |
13 | subi temp1,10 |
14 | dv2: dec temp4 ;Das ganze 16 mal |
15 | brne dv1 |
16 | ;------------------------------------------------- |
17 | ; Ende Div Routine. |
18 | ;------------------------------------------------- |
19 | ret |
Das kann man sicher optimieren. 200=2*2*2*5*5 Die 2*2*2 lassen sich durch eine Verschiebung nach rechts realisieren. Für die 25 lässt sich bestimmt auch was finden.
/25? 25=0x11001; Das Ergebnis sollt sich in 5 Schritten berechnen lassen.
Hallo, falls doch zusätzlich zur Ausgangzahl (R1) noch Platz für ein Zahl gleicher Größe (R2) vorhanden ist, kann man diese Variante div100 ja anwenden. http://www.tiac.net/~cri/2002/divide100.html Ohne Vergleiche nur simples schieben und addieren.
Wer Code-sparend rechnen will, sollte bedenken: - Addieren / Subtrahieren ist "billig". - Multiplizieren "teuer" - Dividieren (außer durch Vielfache von 2) "Luxus" Also, wenn du vorher vielleicht schon multiplizieren musstest: Multipliziere doch so, dass du durch 256 teilen musst!
Hallo, sehr code-sparend ist doch schon die Variante von juergen_w Beitrag "Re: Teilen durch 200 in ASM" und braucht nur 2 Byte extra für Schleifenzähler und Rest. Die Laufzeit war R. Freitag ja nicht wichtig und ~210 Takte ist ja so schlimm nicht für 16 bit / 8 Bit. Man muss halt seine Ausgangszahl in Temp2/Temp3 eventuell vorher in Sicherheit bringen.
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.