Forum: Mikrocontroller und Digitale Elektronik Wurzel ziehen in AVR-Assembler


von Paul Baumann (Gast)


Lesenswert?

Mir ist gerade aufgefallen, daß man in AVR-Assembler wohl gar keine
Quadratwurzel ziehen kann?!

Beispiel: U=Wurzel(P*R)
In Bascom würde ich jetzt P und R als Byte auslegen (Reicht bei mir hin)
und U als Word und den Befehl SQRT nehmen.

In Assembler (nur als Pseudocode)
ldi R16,P
ldi R17,R

Lsl und lsr multiplizieren/dividieren ja nur mit/durch 2

So und jetzt fehlt der Befehl "mul" und "sqrt" auch. Außerdem müßte ich 
das
Ergebnis ja in einem Doppelregister unterbringen, da zumindest das 
Zwischenergebnis "dicker" als ein Byte wird.

Das ist nicht "lebensnotwendig" für mich, nur grüble ich darüber nach.

MfG Paul

von Compy (Gast)


Lesenswert?

Gehen tut das schon: 
http://de.wikipedia.org/wiki/Babylonisches_Wurzelziehen
Man muss halt Algorithmen benutzen.

Die ATmega-Bausteine haben zudem eine ganze Stange mul-Instruktionen :-)

von AVRFan (Gast)


Lesenswert?

>So und jetzt fehlt der Befehl "mul" und "sqrt" auch.

Die aktuellen AVRs verfügen über den Befehl "mul".  Einen 
Assemblerbefehl zum Wurzelziehen gibt es allerdings wirklich nicht, weil 
das keine "einfache Operation" mehr ist . Es steht Dir aber drei, eine 
"sqrt"-Routine zu schreiben, die das Gewünschte mit entsprechend vielen 
vorhandenen Instruktionen erledigt.  Schau mal im Artikel 
AVR-Arithmetik, darin findest Du eine solche:

http://www.mikrocontroller.net/articles/AVR-Tutorial:_Arithmetik#Wurzel

von Bensch (Gast)


Lesenswert?

Ist nicht gerade üblich, mit einem solchen Controller Wurzeln zu ziehen. 
Wenn die Genauigkeit ausreicht, am besten und schnellsten mit einer 
Tabelle.

von AVRFan (Gast)


Lesenswert?

>es steht Dir aber drei...  soll natürlich FREI heißen :-)

von Paul Baumann (Gast)


Lesenswert?

Ich habe nur hier gesucht:
http://www.avr-asm-tutorial.net/avr_de/beginner/index.html
weil mir das bis jetzt unheimlich gut half. Aber dort führt er den 
Befehl
"mul" nicht auf.

Danke für Deinen Link, ich sehe schon, daß das eine unheimliche 
Schleifenkonstruktion werden wird. Mein lieber Mann. ;-)

Wie gesagt: Es ist in Bascom schon fertig und geht auch prima; ich 
wollte
nur mal sehen, ob ich das irgendwie auch in Assembler schaffe.

MfG Paul

von Paul Baumann (Gast)


Lesenswert?

Gut, da will ich mir mal ein großes Blatt nehmen und gucken, was 
Bernhard sich 
da:http://www.mikrocontroller.net/articles/AVR-Tutorial:_Arithmetik#Wurzel

überlegt hat.

Danke Euch einstweilen für die Hinweise.

MfG Paul

von AVRFan (Gast)


Lesenswert?

>Aber dort führt er den Befehl"mul" nicht auf.

Dann ist diese Site wohl nicht ganz up-to-date.  Den meisten (allen?) 
Quadratwurzel-Routinen dürfte übrigens der schon in der Antike bekannte 
Heron-Algorithmus zugrundeliegen.

Siehe http://de.wikipedia.org/wiki/Heron-Verfahren

von Simon K. (simon) Benutzerseite


Lesenswert?

Paul Baumann wrote:
> Ich habe nur hier gesucht:
> http://www.avr-asm-tutorial.net/avr_de/beginner/index.html
> weil mir das bis jetzt unheimlich gut half. Aber dort führt er den
> Befehl
> "mul" nicht auf.

Tja, dann sollte man wohl in die Instruction Summary (Datenblatt) oder 
die ausführliche Version (Atmel Appnote) schauen.

von Markus (Gast)


Lesenswert?

Schau mal auf
http://elm-chan.org/cc_e.html
bei
AVR libraries for ASM projects

Da gibts u.a. Libs in ASM für 16 und 32 Bit Wurzelziehen

von Paul Baumann (Gast)


Lesenswert?

Aha. Ich habe mir jetzt das Beispiel aus dem "hiesigen" Tutorial 
vorgenommen und habe das erfolgreich ausprobiert. Das war nicht einfach 
zu verstehen, aber nach ein wenig Beobachten im AVR-Studio habe ich 
gesehen, wie er es gemacht hat. Ein Fuchs!

MUL und MULSU habe ich jetzt auch gefunden (Mega8 Datenblatt)

Trotzdem habe ich noch noch ein Problem: Wie formuliere ich das?

Ldi R16,100
Ldi R17,200

und jetzt?

Mul r16,17 ?

Das wird nicht gehen, weil das Ergebnis 20000 ist und somit nicht
in ein "normales" Register passt. Die englische Befehlsbeschreibung
ist mir nicht klar geworden, mit Übersetzungsprogramm kommt ziemlicher 
Stuss heraus.

Kann mir mal jemand auf die Sprünge helfen?

MfG Paul

von spess53 (Gast)


Lesenswert?

Hi

Das Ergebnis steht nach der Multiplikation in r1:r0 (High/Low-Byte).

MfG Spess

von 1234 (Gast)


Lesenswert?

>Die englische Befehlsbeschreibung ist mir nicht klar geworden, mit 
>Übersetzungsprogramm kommt ziemlicher Stuss heraus.

Paul,
du solltes in Betracht ziehen englisch zu lernen, da du ohne in diesem 
Geschaeft nicht sehr weit kommst. Freu dich, dass es nicht japanisch 
ist. Da hatten wir einfach Glueck.

von Paul Baumann (Gast)


Lesenswert?

@Spess53

Danke. Das habe ich gerade mal ausprobiert. Da muss erst mal einer drauf 
kommen, daß sich das Ergebnis in R1 und R0 "rumsielt" ;-)

Wieder was gelernt.

MfG Paul

von Paul Baumann (Gast)


Lesenswert?

@1234
Mir wäre es lieber, die Datenblätter wären in Russisch. ;-)

Nein, im Ernst: Ich bin ein alter Zausel, der in der Schule noch kein 
Englisch hatte. "Normale" englische Texte verstehe ich zwar sinngemäß, 
aber
technisch kompliziertere Sachen nicht. Ich mache das Ganze auch nicht 
beruflich, nur hobbymäßig.
Manchmal passiert es eben, daß man Probleme mit den mir bis jetzt 
bekannten
Befehlen nicht lösen kann und dann habe ich hier meist gute und 
vernünftige Hilfe erhalten. Klar, manch einer, der das jeden Tag 8 
Stunden macht, denkt: "Was ist denn das für ein Reddel?", aber bei mir 
ist es meist nicht das Problem: Wie mache ich das, sondern wie sag ich 
es meinem
Assembler. :-)

MfG Paul

von spess53 (Gast)


Lesenswert?

Hi

Eine ausführliche Beschreibung der Befehle findest du in der AVR Studio 
Hilfe Assembler->Instructions oder hier:

www.atmel.com/dyn/resources/prod_documents/doc0856.pdf

MfG Spess

von Paul Baumann (Gast)


Lesenswert?

Die .pdf-Datei habe ich mir hergeholt. Am Besten wird sein, die Befehle,
die ich noch nicht brauchte, nach und nach zu testen und eine deutsche 
Beschreibung dazu zu machen. Ich müßte bloß mal den Onkel Atmel 
anmailen,
ob ich das dann auf meiner Seite veröffentlichen darf.

MfG Paul

von yalu (Gast)


Lesenswert?

Paul Baumann schrieb:
> "Normale" englische Texte verstehe ich zwar sinngemäß, aber
> technisch kompliziertere Sachen nicht.

Interessant, da geht's mir gerade andersherum: Das Datenblattenglisch
hat einen Wortschatz von ein paar hundert Wörtern, von denen die
meisten auf Deutsch genau gleich heißen. Eine amerikanische Zeitung zu
lesen ist schon deutlich schwieriger, die Krönung sind aber immer noch
englische Witze ;-)

> Am Besten wird sein, die Befehle, die ich noch nicht brauchte, nach
> und nach zu testen und eine deutsche Beschreibung dazu zu machen.
> Ich müßte bloß mal den Onkel Atmel anmailen, ob ich das dann auf
> meiner Seite veröffentlichen darf.

Warum solltest du den Onkel fragen müssen? Wenn du die Texte aus dem
Datenblatt nicht einfach übersetzt (was dir ja offensichtlich sowieso
nicht liegt), sondern selbst formulierst, hast du ein eigenes Werk
geschaffen, das du natürlich auch veröffentlichen darfst. Vielleicht
freut sich der Onkel sogar darüber, dass du damit die Popularität
seiner AVRs auch unter den nicht Englischkundigen steigerst :)

von Simon K. (simon) Benutzerseite


Lesenswert?

Paul Baumann wrote:
> @Spess53
>
> Danke. Das habe ich gerade mal ausprobiert. Da muss erst mal einer drauf
> kommen, daß sich das Ergebnis in R1 und R0 "rumsielt" ;-)
>
> Wieder was gelernt.

Das beste ist, dass man nicht darauf kommen muss sondern man kann es 
einfach genüsslich lesen ;)

Wenn du auch nicht so gut englisch kannst (passiert schonmal) kannst du 
dir auch die Befehle beispielsweise in der AVR-Studio Assemblerhilfe 
angucken. (Einfach den Cursor in ein Assembler-Mnemonic reinsetzen und 
F1 drücken).

Da stehen dann so Sachen wie:
1
Operation:
2
3
(i) R1:R0 <- Rd × Rr(unsigned <- unsigned × unsigned)

Sprich
- R1:R0 (Doppelpunkt wegen Wert, der über mehrere Register geht)
- Pfeil (<-) ist eine Zuweisung
- Der Stern stellt eine mathematische Multiplikation dar.
- Rd * Rr sind die Operanden (mit der du den Befehl "aufrufst")

Zu sehen dadrunter:
1
Syntax:          Operands:                        Program Counter:
2
3
(i) MUL Rd,Rr    0 ≤ d ≤ 31, 0 ≤ r ≤ 31           PC ← PC + 1
Da steht Sinngemäß
- Die Syntax (ist klar). Also wie der Befehl verwendet wird. (Und wie 
die Operanden heißen)
- Der Gültigkeitsbereich der Operanden (beide gehen von einschließlich 
Null bis einschließlich 31). D.h.: auf Register r0 bis r31 anwendbar.
- Was mit dem Programcounter passiert (also der "Zeiger", der im Flash 
auf die aktuell ausgeführte Programmzeile zeigt). Ist aber eigentlich 
nur bei Sprüngen usw. wichtig.

Also durchaus eine Alternative zu der englischen Sprache.

PS: Ganz unten auf der Hilfeseite steht noch, welche und wie diese 
Prozessorflags beeinflusst werden durch diesen Befehl. Aber wie das 
funktioniert darfst du selber heraus finden ;)

von Michael U. (amiga)


Lesenswert?

Hallo,

genau diesen Vorschlag wollte ich auch gerade machen...
Wenn man erstmal verstanden hat, welchen Sinn diese "Formeln" in den 
Datenblättern haben und welche besonderheiten ein Hersteller da benutzt, 
spart man sich viel Kopfzerbrechen um englische Texte.

Wichtig ist auch, auf Kleingedrucktes dort zu achten und die Darstellung 
der Flagbeeinflussung.

Paul wird das Problem da erstmal weniger haben, ich bin aber über die 
Besonderheit* schon gestolpert, daß der AVR bei INC/DEC das C-Flag nicht 
beeinflußt und mein BRCS nicht ausgeführt wurde.

* weil andere CPUs das durchaus anders behandeln. ;)

Die Assemblerhilfe des AVRStudios ist da schon sehr praktisch, weil 
schnell zur Hand.

Gru0 aus Berlin
Michael

von Paul Baumann (Gast)


Lesenswert?

@Simon
Das ist prima, daß Du das so ausführlich erklärt hast. Da die 
Beschreibung
bei allen Befehlen ziemlich ähnlich gemacht ist, hilft mir das ungemein 
weiter (und vielleicht auch Anderen, die im Hintergrund sitzen)

Vielleicht könnte man Andreas bitten, Deinen Text vom 2. Absatz an in 
das
Tutorial einzufügen.

Danke Dir
Paul

von Condi (Gast)


Lesenswert?


von mr.chip (Gast)


Lesenswert?

> Nein, im Ernst: Ich bin ein alter Zausel, der in der Schule noch kein
> Englisch hatte. "Normale" englische Texte verstehe ich zwar sinngemäß,
> aber technisch kompliziertere Sachen nicht.

Wenn du normale englische Texte verstehst, dann geht das auch mit den 
Datenblättern schnell. Tip: dict.leo.org ist ein sehr gutes 
Online-Wörterbuch. Schlage konsequent alle Begriffe nach, die du nicht 
verstehst - nach recht kurzer Zeit wirst du die Datenblätter völlig 
problemlos verstehen, denn eigentlich ist das Englisch recht einfach, 
wenn man mal die 10-20 wichtigsten Redewendungen sowie die 20-50 
wichtigsten Begriffe kennt.

Datenblätter auf Deutsch übersetzen bringt nicht viel, denn sowas 
braucht wirklich kaum jemand. Heute lernen sämtliche Leute englisch in 
der Schule und wer früher kein Englisch hatte und sich im Informatik- 
und Elektronikbereich bewegt, der tut gut daran, es zu lernen.

von Paul Baumann (Gast)


Lesenswert?

@Condi
Das wird ja immer besser. :-) Da hätte ich das Fahrrad bald noch einmal 
erfunden. Das habe ich beim Suchen nicht gefunden.

@Mr.Chip
Guter Rat von Dir. Mein Sohn hat in der Schule auch Englisch gelernt, 
liest auch "wie ein Mann" Texte und übersetzt sie simultan, aber wenn
es an Sachen geht, bei denen ihm der technische Hintergrund fehlt, ist
auch "Pumpe".

Zündender Gedanke war die Erklärung von Simon weiter oben.

Jetzt schmeiße ich alle Sachen außer dem System und AVR-Studio von 
meiner Platte, damit ich genug Platz für meine Assembler-Dateien habe.

ganz breites Grinsen

MfG Paul

von Dieter W. (dds5)


Lesenswert?

Und nicht wundern wenn plötzlich mal was komisches übersetzt wird.

Displacement z.B. heisst nicht nur Sprungweite sondern auch Hubraum.

von Paul Baumann (Gast)


Lesenswert?

Thank you!

Ja, das wäre nicht so gut, ein Atmega8 mit 3 Litern Hubraum....;-)))

Hef a neiß D!

Paul

von gerd (Gast)


Lesenswert?

@ Paul

Habe den "mul" jetzt auch beschrieben:

http://www.avr-asm-tutorial.net/avr_de/rechnen/hardmult.html

Geht aber nur bei ATmega!

mfg
gerd

von Paul Baumann (Gast)


Lesenswert?

@Gerd
Príma. Ich habe Dein Tutorial schon immer gerne benutzt, weil Du das 
schön anschaulich erklärst.

MfG Paul

von Tom (Gast)


Lesenswert?

und jetzt zum Wurzelziehen:

w = sqrt(x)
Ein Variable wird von 1 ausgehend in Zweierschritten erhöht, und 
aufaddiert. Wenn die Summe größer ist als x, dann ist die Anzahl 
Additionen = w.

1+3 = 4
1+3+5 = 9
1+3+5+7 = 16
etc.

Kann man sicher in 10 Zeilen Assembler hinkriegen.

von Clemens H. (sum)


Lesenswert?

Letzthin habe ich eine sehr interessante Seite zum Wurzelziehen 
gefunden:
http://www.azillionmonkeys.com/qed/sqroot.html

Wobei mich vor allem eine Methode besonders interessant fand:
1
Let us examine an implementation of the second method:
2
3
  /* by Jim Ulery */
4
  static unsigned julery_isqrt(unsigned long val) {
5
      unsigned long temp, g=0, b = 0x8000, bshft = 15;
6
      do {
7
          if (val >= (temp = (((g << 1) + b)<<bshft--))) {
8
             g += b;
9
             val -= temp;
10
          }
11
      } while (b >>= 1);
12
      return g;
13
  }

Hierbei braucht man nicht wie bei Tom maximal 65536 Schleifendurchläufe 
für eine 32Bit Wurzel sondern lediglich 16 (siehe ausgerollte Schleife).
Ich denke das sollte auch kein zu großes Problem sein, diesen Code in 
Assembler zu formulieren.

Achja, so undurchsichtig das auch ist, weiter oben ist die Erklärung, 
die ich mir auch nicht reingezogen habe, aber der C-Code geht wenigstens 
;-)

Grüße,
 Clemens

von Hagen (Gast)


Lesenswert?

Die Erklärung hat Tom (gast) schon gegeben. Seine Methode kann man 
vereinfachen wenn man mit Potenzen zu 2 rechnet, und das macht dann dein 
geposteter C Code.

Gruß Hagen

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.