Forum: Mikrocontroller und Digitale Elektronik Teilen durch 200 in ASM


von R. F. (rfr)


Lesenswert?

Hallo

ich suche Möglichkeiten, in AVR-Assembler  durch 200 zu teilen, und zwar 
möglichst effezient. Also fast ohne Speicherplatzverbrauch.

Gruss

Robert

von spess53 (Gast)


Lesenswert?

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

von R. F. (rfr)


Lesenswert?

16 und 32 bit.

von spess53 (Gast)


Lesenswert?


von Eumel (Gast)


Lesenswert?

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

von heldvomfeld (Gast)


Lesenswert?

Servus, kann man nicht einfach 3x Shiften? also um 7, um 6 und um 3? 
Oder führt das nicht zum Ziel?

gruß~

von m0t0r (Gast)


Lesenswert?

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.

von Jürgen W. (juergen_w) Benutzerseite


Lesenswert?

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

von chris (Gast)


Lesenswert?

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.

von chris (Gast)


Lesenswert?

/25?

25=0x11001;

Das Ergebnis sollt sich in 5 Schritten berechnen lassen.

von chris (Gast)


Lesenswert?


von Horst H. (horha)


Lesenswert?

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.

von Kurt (Gast)


Lesenswert?

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!

von Horst H. (horha)


Lesenswert?

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
Noch kein Account? Hier anmelden.