Forum: Mikrocontroller und Digitale Elektronik Division 64Bit durch 32Bit gesucht


von Bernhard S. (bernhard)


Lesenswert?

Geschätztes Forum,

ein 64Bit Zahl, soll durch eine 32Bit Zahl In Assembler z.B. ATmega8 
dividiert werden.

Siehe 32Bit Division:
https://www.mikrocontroller.net/articles/AVR_Arithmetik#32_Bit_.2F_32_Bit

Kann jemand helfen?

Danke Bernhard

:
von S. R. (svenska)


Lesenswert?

Schreib das mal in C hin, wirf das dem Godbolt vor die Nase und schau 
dir an, was der daraus macht. Besser kannst du das auch nicht.

von Pandur S. (jetztnicht)


Lesenswert?

Bei uns lernten wir in der Schule für die Kleinen noch schriftlich 
dividieren. Jetzt machst du genau dasselbe nochmals. Aber in Binaer.
Das ist sogar viel einfacher, wenn man's erkannt hat.

Mach's einfach.

von Andreas B. (bitverdreher)


Lesenswert?

Mit 32 und 16 bit steht es hier weiter unten:
http://avr-projekte.de/rechnen.htm

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

Bernhard S. schrieb:
> Kann jemand helfen?

Wobei genau brauchts denn Hilfe?

Jedenfalls hatte ich mal einen Hardware Dividierer gebaut, daher auch 
mal etwas Theorie zusammengetragen und verfasst:
Beitrag "Re: Space Age 2 der 32Bit MIPS Rechner in TTL"

Erstmal die, bereits oben genannte, Theorie des binären schriftichen 
dividierens und dann die Umsetzung in C Testcode.
Den kannste ja auf 64Bit aufblasen und dan Dissasembler befragen oder 
selber bauen in asm.

Die Ablaufdiagramme diverser Fachbücher haben leide Sonderfälle 
weggelassen.

Achja, willste signed oder unsigned?
Ist bei der Binärdivision nen größerer Unterschied ;)

von Walter T. (nicolas)


Lesenswert?

Pandur S. schrieb:
> Aber in Binaer.
> Das ist sogar viel einfacher, wenn man's erkannt hat.

Leider nein. Im "Hacker's delight" hat allein die Integer-Division knapp 
100 Seiten in zwei Kapiteln. Und das nicht, weil sich der Autor nicht 
kurz fassen kann.

: Bearbeitet durch User
von Peter D. (peda)


Lesenswert?

Wenn man die 8Bit Division verstanden hat, ist es ein leichtes, sie auf 
64Bit aufzubohren.
Man braucht die beiden Operanden und einen temporären Speicher. Der AVR 
hat 32 Register, man kann also problemlos bis auf 80Bit erweitern.

Wie schon gesagt wurde, kann man es auch in C hinschreiben und nach 
Assembler übersetzen lassen.

von Edson (Gast)


Lesenswert?

Peter D. schrieb:
> Wie schon gesagt wurde, kann man es auch in C hinschreiben und nach
> Assembler übersetzen lassen.

Ganz so ist es dann auch wieder nicht. Der Compiler erzeugt zwar 
ASM-Code aus den C-Quellen, aber das Compilat ist und bleibt ein 
C-Programm.
Das schlichte Übersetzen einer Hochsprache nach Assembler ist ja gar 
nicht möglich, deswegen heisst ein Compiler nicht Translator.

SCNR

(in letzter Zeit hatte ich den Eindruck, hier gehen langsam die 
Grundlagen flöten...natürlich nicht bei Dir, Peda)

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Bernhard S. schrieb:
> ein 64Bit Zahl, soll durch eine 32Bit Zahl In Assembler z.B. ATmega8
> dividiert werden.
Ist das schon die eigentliche (Haus)Aufgabe oder ist das Teil eines 
Lösungsansatzes für ein Problem?

Denn wenn du ein Problem hast, das in Assembler auf einem 8-Bit Rechner 
mit 64 Bit (oder auch nur 32 Bit) Variablen gelöst werden muss, dann 
passt für mich irgendwas irgendwie nicht richtig zusammen.

von Nils D. (Gast)


Lesenswert?

Walter T. schrieb:
> Pandur S. schrieb:
>> Aber in Binaer.
>> Das ist sogar viel einfacher, wenn man's erkannt hat.
>
> Leider nein. Im "Hacker's delight" hat allein die Integer-Division knapp
> 100 Seiten in zwei Kapiteln. Und das nicht, weil sich der Autor nicht
> kurz fassen kann.

Wer den Schwachsinn ernst nimmt hat nichts verstanden.

von m.n. (Gast)


Lesenswert?

Lothar M. schrieb:
> Ist das schon die eigentliche (Haus)Aufgabe oder ist das Teil eines
> Lösungsansatzes für ein Problem?

Man muß hier nur ein wenig querlesen und kann erkennen, daß Bernhard 
wohl für seinen Frequenzzähler eine passende Division sucht: 
Beitrag "Problem 16Bit Timer auslesen und zurücksetzen für Frequenzzähler ATmega1284p Assembler"

Im Grunde ist eine Funktion für 64:32 reine Fleißarbeit, bringt aber bei 
der vermuteten Anwendung noch nicht den richtigen Durchbruch aber viele 
Fehlerquellen.
Entweder würde ich die Berechnungen in C formulieren und dem Compiler 
überlassen, oder gleich Routinen schreiben/verwenden, die double 
Variablen verwenden.
Lösung per Compiler: Beitrag "reziproker Frequenzzähler, GPS-stabilisiert, ATmega162"
oder spezielle Funktionen: 
Beitrag "64 Bit float Emulator in C, IEEE754 compatibel"

In Assembler zu programmieren ist bei solchen Berechnungen nicht mehr 
die Lösung sondern eher das Problem.
Selbst Compiler für die kleinsten ARM (M0) bieten schon 
double-Berechnungen in C.
Wenn wir schon dabei sind: ein reziproker Zähler wäre zeitgemäß und 
flexibler .....

von Peter D. (peda)


Lesenswert?

Edson schrieb:
> Das schlichte Übersetzen einer Hochsprache nach Assembler ist ja gar
> nicht möglich, deswegen heisst ein Compiler nicht Translator.

-fverbose-asm
erzeugt ein *.s File.
Das enthält allerdings nur den Aufruf der Lib-Funktion.
Daher ist es besser, sich das .lss File anzuschauen, das enthält den 
gesamten Assemblercode.

: Bearbeitet durch User
von (prx) A. K. (prx)


Lesenswert?

Edson schrieb:
> Das schlichte Übersetzen einer Hochsprache nach Assembler ist ja gar
> nicht möglich, deswegen heisst ein Compiler nicht Translator.

Apropos fehlende Grundlagen - so las sich das früher einmal:
1
◊UEBERSETZE, QUELLE=/BEGIN print(("Grüß Gott!", new line)) END◊/, SPRACHE=ALG68

: Bearbeitet durch User
von Bernd (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,
ich habe mal vor einiger Zeit für einen PIC eine 16-Bit-Division in 
Assembler programmiert. Das Prinzip ist tatsächlich wie schriftliches 
Dividieren in der Grundschule, nur auf binär umgesetzt. Ich weis jetzt 
nicht wie sehr sich PIC und ATmega unterscheiden, das Prinzip sollte 
sich problemlos auf 64 Bit/ 32 Bit aufblasen lassen. Vielleich nützt es 
was.
Bernd

von Peter D. (peda)


Angehängte Dateien:

Lesenswert?

Anbei aus früheren Assemblertagen.

von Bernhard S. (bernhard)


Lesenswert?

Peter D. schrieb:
> Anbei aus früheren Assemblertagen.

Super, es werden ziemlich viele Register benötigt, sicherlich lässt sich 
einiges im SRAM auslagern, wird natürlich dadurch etwas langsamer.

a0...a7 Divident ?
b0...b7 Divisor  ?
t0...t7 Hilfsregister ?

Bernd schrieb:
> Vielleich nützt es was.

Danke Bernd für Dein Beispiel

Lothar M. schrieb:
> Denn wenn du ein Problem hast, das in Assembler auf einem 8-Bit Rechner
> mit 64 Bit (oder auch nur 32 Bit) Variablen gelöst werden muss, dann
> passt für mich irgendwas irgendwie nicht richtig zusammen.

Deine Aussage verstehe ich nicht, ein 8Bit-er kann doch problemlos mit 
16Bit und höher rechnen, oder gibt es eine Begrenzung?

von LDA ($F0),Y (Gast)


Lesenswert?

Peter D. schrieb:
> Anbei aus früheren Assemblertagen.

Tjaaaa, da braucht es schon ein "paar" AVR Registerchen ....

von Wolfgang (Gast)


Lesenswert?

Walter T. schrieb:
> Leider nein. Im "Hacker's delight" hat allein die Integer-Division knapp
> 100 Seiten in zwei Kapiteln. Und das nicht, weil sich der Autor nicht
> kurz fassen kann.

Das glaube ich nicht - ich meine das das nicht am Autor liegt.
Wenn man von Hand schriftlich dividiert, macht man das doch auch 
rekursiv Schritt für Schritt und ohne 100 Blatt Papier dafür zu 
brauchen.

Beitrag #6655137 wurde von einem Moderator gelöscht.
von Rainer V. (a_zip)


Lesenswert?

Walter T. schrieb:
> Leider nein. Im "Hacker's delight" hat allein die Integer-Division knapp
> 100 Seiten in zwei Kapiteln. Und das nicht, weil sich der Autor nicht
> kurz fassen kann.

Kann ich jetzt auch nicht glauben...bin aber zu faul zu 
suchen...vielleicht zeigste mal einen Link?!
Gruß Rainer

von Oliver S. (oliverso)


Lesenswert?

Edson schrieb:
> Der Compiler erzeugt zwar
> ASM-Code aus den C-Quellen, aber das Compilat ist und bleibt ein
> C-Programm.

Nur, wenn der Compilerbauer die Division in C geschrieben hätte.
Da das aber mit an Sicherheit grenzender Wahrscheinlichkeit nicht der 
Fall ist, sind die Divisionsroutinen weder ein Compilat, noch ein 
C-Programm.

Oliver

von Sascha W. (sascha-w)


Angehängte Dateien:

Lesenswert?

Hier noch eine Variante die die Werte direkt im SRAM berechnet um den 
"Verbrauch" an Registern zu minimieren.
Hab ich mir mal für den BME280 geschrieben.

Sascha

von Eberhard H. (sepic) Benutzerseite


Lesenswert?

Achtung: Der letzte Code von Peter D. ist 64Bit/64Bit.

Bei den gesuchten 64Bit/32Bit schaut es etwas sparsamer bezüglich 
Registern aus.

Es reichen sogar alle "unteren" Register R0..R15 (+ der Schleifenzähler 
im "oberen" Register-Bereich):
1
;   Dividend64 / Divisor32 = Quotient64 + Rest32
2
3
;   r15:r14:r13:r12:r11:r10:r9:r8 / r7:r6:r5:r4 
4
; = r15:r14:r13:r12:r11:r10:r9:r8 Rest r3:r2:r1:r0
5
6
DIV64_32:
7
  clr  r0
8
  clr  r1
9
  clr  r2
10
  clr  r3
11
  ldi  r16, 64
12
schieben:
13
  lsl  r8
14
  rol  r9
15
  rol  r10
16
  rol  r11
17
  rol  r12
18
  rol  r13
19
  rol  r14
20
  rol  r15
21
  rol  r0
22
  rol  r1
23
  rol  r2
24
  rol  r3
25
  cp   r0, r4
26
  cpc  r1, r5
27
  cpc  r2, r6
28
  cpc  r3, r7
29
  brcs next
30
  sub  r0, r4
31
  sbc  r1, r5
32
  sbc  r2, r6
33
  sbc  r3, r7
34
  inc  r8
35
next:
36
  dec  r16
37
  brne schieben
38
  ret

Das ist auf jeden Fall schneller und deutlich sparsamer bezüglich 
Programmspeicher und SRAM/Stack als ein von C erzeugter Code.

: Bearbeitet durch User
von Kurt (Gast)


Lesenswert?

Habe das Thema jetzt erst entdeckt. Sieht so aus, wie meine
32/16 Bit Division - nur um das Nötige aufgebohrt...

Wer Angst vor ASM hat, soll sich halt hinterm Compiler verstecken,
Mund halten und nicht bedenkenträgerischen Unsinn kommunizieren.

Als brauchbare Funktion in einem umfangreicheren Programm,
müssen natürlich noch alle Register gepusht und gepopt werden,
wahrscheinlich auch die Daten aus dem RAM in die Register (und
zurück) kopiert werden.

Aber das alles muss der C-Compiler auch bereitstellen...

Und wenn das ganze auch noch "signed" sein soll, ist es auch
kein Hexenwerk:
Wenn Dividend, oder Divisor negativ sind, werden sie halt von
einer Null mit entsprechender Bit-Zahl subtrahiert, also
negiert. In einem zusätzlichen Register wird vermerkt, ob
einer, oder beide, oder keiner negativ war.
Die Division erfolgt dann mit dem Absolutwert - zum Schluss
mus das Ergebnis wieder negiert werden, wenn (!) nur einer von
beiden negativ war.

Aber das alles muss der C-Compiler auch bereitstellen...

von Bernhard S. (bernhard)


Angehängte Dateien:

Lesenswert?

Division 64 durch 64 Bit (ohne Vorzeichen):

Vorteil: wenig Register

8 Register R0 ...R7
8 Register R16...R24
16 SRAM-Bytes

Nachteil: rechenintensiver

Hinweis: Excel kann nur bis 48Bit genau rechnen

Mit etwas Fleiß lassen sich die Register
R0 bis R7 und R16 bis R24 auch durch SRAM-Bytes ersetzen :-)

: Bearbeitet durch User
von Kurt (Gast)


Lesenswert?

@ Bernhard S

Du fragst nach Hilfe für 64/32 und Eberhard H. liefert das
optimale Ergebnis für dein genanntes Problem. Ohne Vorzeichen.
Von mir kamen noch Hinweise, wie du auch mit Vorzeichen zum Ziel
kommst.
Jetzt fährst du eine mittelprächtige Lösung für ein größeres
Problem (64/64) aber ohne Vorzeichen auf. Gääähn!

Willst du uns trollen???

von Rainer V. (a_zip)


Lesenswert?

Kurt schrieb:
> Willst du uns trollen???

wahrscheinlich schon von Anbeginn...
die Welt ist schlecht...meine Mutter schrieb mir früher immer einen 
Entschuldigungszettel mit "Rainer war schlecht", kein Witz!
Gruß Rainer

von Peter D. (peda)


Lesenswert?

Bernhard S. schrieb:
> Vorteil: wenig Register

Warum soll das ein Vorteil sein?
Für unbenutzte Register gibt es kein Geld zurück.

von Kurt (Gast)


Lesenswert?

Ja, der eine sieht 100 Seiten "Hacker's Delight" (bin bisher ohne
ausgekommen) und traut sich garnicht erst ran. ABER kommuniziert
bedenkenträgerisch-ahnungslose Warnungen, wenn nur das Kürzel ASM
sichtbar wird.

Die meisten leben glücklicher,
(1) wenn sie sich bei ASM etwas nach Vorschlägen umgucken und
    sich daraus ihre Lösung optimieren, oder
(2) wenn sie gleich Hochsprache nehmen, oder
(3) wenden sich einem Hobby wie Ikebana, oder Wrestling (auf
    dem Sofa mit Chips und Bier) zu...

von Bernhard S. (bernhard)


Lesenswert?

> Du fragst nach Hilfe für 64/32 und Eberhard H. liefert das
> optimale Ergebnis

Euch danke und bewundere ich,
schmücken mit Medaillen und adeln sollte man Euch, ich bin super extrem 
maximal begeistert!

Ein Problem trat jedoch auf, das ahnte ich vorher nicht, es stehen mir 
nur noch 12 untere Register zur Verfügung, Eberhards Lösung verlangt 16.

Aber, man könnte natürlich Eberhards untere Register in die oberen 
verlagern, dort stünden bei mir noch 16 Register zur Verfügung.

von boooaaahh (Gast)


Lesenswert?

Bernhard S. schrieb:
> Euch danke und bewundere ich

Ich frage mich nur warum du hier einen Thread auf der Suche nach
einer Lösung aufmachst und schliesslich und endlich deine "eigene",
"bessere" Lösung daherbringst.

Was soll der Krampf?

von Bernhard S. (bernhard)


Lesenswert?

> Ich frage mich nur warum du hier einen Thread auf der Suche nach
> einer Lösung aufmachst und schliesslich und endlich deine "eigene",
> "bessere" Lösung daherbringst.

Ich hätte Anfangs die Bedingungen auflisten sollen, sorry:

Bedingungen:

- Rechenzeit bis 1,9s bei 20MHz Takt
- maximal 12 untere Register, alle oberen stehen komplett zur Verfügung
- SRAM 15k Verfügbar
- Code kann lang sein, genügend Reserve steht zur Verfügung

von Bernhard S. (bernhard)


Angehängte Dateien:

Lesenswert?

Eberhard H. schrieb:
> Es reichen sogar alle "unteren" Register R0..R15
>(+ der Schleifenzähler im "oberen" Register-Bereich)

Eine sehr elegante Lsung, hast was gut bei mir.

Hab mal einige der "unteren" Register in "obere" gwandelt, läuft 
perfekt.

von m.n. (Gast)


Lesenswert?

Bernhard S. schrieb:
> Hinweis: Excel kann nur bis 48Bit genau rechnen

Beim IEEE 754 double Format hat die Mantisse 52 Bit. Intel FPUs rechnen 
intern im "extended precision format" wobei die Mantisse 63 Bit lang 
ist. Und Du glaubst, dies mit Deinen 64 Bit Integer-Berechnungen zu 
übertreffen?
Weit gefehlt!

Bei Deinen Rechnungen wird regelmäßig der Rest einer Division gnadenlos 
weggeworfen. Der Wertebereich der Zahlen ist bescheiden. Ja, ja, 
Fixkomma und so - vergiss es.

Bernhard S. schrieb:
> Bedingungen:
>
> - Rechenzeit bis 1,9s bei 20MHz Takt

Dann hatte ich ja richtig vermutet. Wenn Du schon etwas 
zusammenstrickst, dann wäre eine Fließkommaberechnung mit 5 Byte (8 Bit 
Exponent und 32 Bit Mantisse) hinreichend und zweckmäßig gewesen, mit 
der man bei guter Dynamik 10 gültige Stellen Auflösung erhält.
Quellcode für 8 Bit CPUs findet man zum Beispiel zu alten 
Commodore-Rechnern (6502 BASIC) wie PET oder C64.

Aber diesen Rat wirst Du wohl erst dann verstehen, wenn die 
Integer-Rechnerei genug Scherereien gemacht hat ;-)

von Bernhard S. (bernhard)


Lesenswert?

m.n. schrieb:
> Bernhard S. schrieb:
>> Hinweis: Excel kann nur bis 48Bit genau rechnen

> Weit gefehlt!

In Excel: 0xffffffffffffffff --> 18.446.744.073.709.500.000

real :    0xffffffffffffffff --> 18.446.744.073.709.551.615

Volltreffer, Hirnchen versenkt ^^

: Bearbeitet durch User
von m.n. (Gast)


Lesenswert?

Ich weiß ja nicht, welche Wahrheit Du Dir da konstruierst. Soll Dein 
Frequenzzähler 20 Stellen liefern?

Zeig mal Ergebnisse nach Deiner 64 Bit Division.
Du mußt noch viel lernen ;-)

von Eberhard H. (sepic) Benutzerseite


Lesenswert?

Bernhard S. schrieb:
> Ein Problem trat jedoch auf, das ahnte ich vorher nicht, es stehen mir
> nur noch 12 untere Register zur Verfügung, Eberhards Lösung verlangt 16.
>
> Aber, man könnte natürlich Eberhards untere Register in die oberen
> verlagern, dort stünden bei mir noch 16 Register zur Verfügung.

Ich habe bewusst die weniger mächtigen "unteren" AVR-Register genommen, 
um nicht unnötig "obere" AVR-Register zu verschwenden.

Genau genommen habe ich geschrieben: "Es reichen sogar alle "unteren" 
Register ..."

Natürlich kann man alle "unteren" AVR-Register oder auch nur einen Teil 
davon immer in "obere" AVR-Register verlegen, aber nicht immer 
umgekehrt.

Die einzige Ausnahme sind R0 und R1, falls man die 
AVR-Multiplikationsbefehle verwendet.

Wenn man die AVR-Register per .def festlegt, kann man die Zuordnung ohne 
großen Aufwand auch nachträglich ändern.

von c-hater (Gast)


Lesenswert?

Eberhard H. schrieb:

> Wenn man die AVR-Register per .def festlegt, kann man die Zuordnung ohne
> großen Aufwand auch nachträglich ändern.

Oder besser gleich als Macro, bei dem sämtliche zu verwendende Register 
Parameter des Macros sind.

So macht es übrigens prinzipiell auch ein guter Compiler...

Der Vorteil eines solchen Vorgehens ist nämlich, daß man mit dem Macro 
wahlweise das tuen kann, was in C als "inlining" bezeichnet wird, also 
beliebig viele Instanzen des Makrocodes mit den bezüglich der 
Aufrufsituation gerade am besten passenden Registern zu erzeugen oder 
aber auch das Gegenteil, also nur eine Instanz, die sich als 
Unterprogramm manifestiert (bei dem dann allerdings natürlich die zu 
verwendenden Register festgenagelt sind).

Der Vorteil in Asm gegenüber dem Compiler ist, dass man die volle 
Kontrolle hat, auch über Situationen, in denen der Compiler sich typisch 
vollkommen doof anstellt.

Das betrifft insbesondere die Codebäume, deren root nicht main() ist.
Da passiert es nämlich regelmäßig, dass sich der Compiler gegen inlining 
entscheidet, wenn eine (auch nur etwas größere) Funktion sowohl im 
main()-Codebaum als auch im in einem anderen verwendet wird. Der weiss 
einfach nicht, das es häufig sehr wichtig ist (kann er nicht wissen), in 
den anderen Codebäumen auf Speed zu optimieren und trifft die falsche 
Entscheidung.
In Assembler hat man die volle Kontrolle und kann eben z.B. entscheiden, 
dass zwar alle Vorkommen des Codes der Funktion in main() in Form eines 
gemeinsamen Unterprogramms geshared werden, für einen anderen Codebaum 
(typisch: ISR) aber eine davon vollkommen getrennte Inkarnation 
desselben Codes (nur halt mit anderer Registernutzung) verwendet wird.

Diese Kontrolle ist (u.a.), was einen fähigen Asm-Programmierer um so 
viel mächtiger macht als einen C-only-Programmierer...

von Peter D. (peda)


Lesenswert?

Bernhard S. schrieb:
> Ein Problem trat jedoch auf, das ahnte ich vorher nicht, es stehen mir
> nur noch 12 untere Register zur Verfügung

Du weißt aber schon, daß man einfach vor der Funktion mit PUSH die 
Register sichern und danach mit POP wiederherstellen kann. Damit kannst 
Du sogar 0 zerstörte Register erreichen.
Und das ist deutlich effektiver, als LD/ST bei jedem Einzelschritt.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Bernhard S. schrieb:
> Lothar M. schrieb:
>> Denn wenn du ein Problem hast, das in Assembler auf einem 8-Bit Rechner
>> mit 64 Bit (oder auch nur 32 Bit) Variablen gelöst werden muss, dann
>> passt für mich irgendwas irgendwie nicht richtig zusammen.
> Deine Aussage verstehe ich nicht
Dann schreibe ich es mal anders: ich würde für diese Aufgabe einfach 
einen 32 Bit Rechner nehmen. Und einen Compiler, der mit langen 
Zahlenformaten umgehen kann.

> ein 8Bit-er kann doch problemlos mit
> 16Bit und höher rechnen, oder gibt es eine Begrenzung?
Er "kann" es. Aber wie der Thread hier ganz offensichtlich zeigt eben 
keineswegs "problemlos" sondern eben nur "umständlich und langsam".

Beitrag #6661486 wurde von einem Moderator gelöscht.
von Eberhard H. (sepic) Benutzerseite


Lesenswert?

Lothar M. schrieb:
> Er "kann" es. Aber wie der Thread hier ganz offensichtlich zeigt eben
> keineswegs "problemlos" sondern eben nur "umständlich und langsam".

Ein ATmega328P (und natürlich ein ATmega1284P u.v.a. ebenso) schafft 
DIV64/32 mit 64 Bit Ergebnis und 32 Bit Rest (besser und genauer geht es 
nicht) mit dem von mir oben aufgelisteten, sehr geradlinigen 
AVR-Assembler-Unterprogramm (nur 60 Bytes Programmspeicher) in ca. 85 
µsec @16 MHz.

von Walter (Gast)


Lesenswert?

(prx) A. K. schrieb:
> Apropos fehlende Grundlagen - so las sich das früher einmal:◊UEBERSETZE,
> QUELLE=/BEGIN print(("Grüß Gott!", new line)) END◊/, SPRACHE=ALG68

hast du auch in Erlangen studiert?
Daher kenne ich TR440 und Algol

Beitrag #6661592 wurde von einem Moderator gelöscht.
Beitrag #6661672 wurde von einem Moderator gelöscht.
Beitrag #6661774 wurde von einem Moderator gelöscht.
Beitrag #6661784 wurde von einem Moderator gelöscht.
Beitrag #6661787 wurde von einem Moderator gelöscht.
Beitrag #6661796 wurde von einem Moderator gelöscht.
Beitrag #6661823 wurde von einem Moderator gelöscht.
Beitrag #6661827 wurde von einem Moderator gelöscht.
Beitrag #6661842 wurde von einem Moderator gelöscht.
Beitrag #6661872 wurde von einem Moderator gelöscht.
von Bernhard S. (bernhard)


Lesenswert?

Peter D. schrieb:
>> Ein Problem trat jedoch auf, das ahnte ich vorher nicht, es stehen mir
>> nur noch 12 untere Register zur Verfügung
>
> Du weißt aber schon, daß man einfach vor der Funktion mit PUSH die
> Register sichern und danach mit POP wiederherstellen kann. Damit kannst
> Du sogar 0 zerstörte Register erreichen.
> Und das ist deutlich effektiver, als LD/ST bei jedem Einzelschritt.

Nur wenn diese Register in den Interrupt-Routinen genutzt werden wird's 
schwierig ;-)

Lothar M. schrieb:
> Er "kann" es. Aber wie der Thread hier ganz offensichtlich zeigt eben
> keineswegs "problemlos" sondern eben nur "umständlich und langsam".

Meine Anwendung erlaubt 1,9 Sekunden Rechenzeit...

: Bearbeitet durch User
von Rainer V. (a_zip)


Lesenswert?

Bernhard S. schrieb:
> Nur wenn diese Register in den Interrupt-Routinen genutzt werden wird's
> schwierig ;-)

also jetzt willst du wieder zanken :-) nichts wird schwieriger...du mußt 
nur mehr "push/pull" machen! Ob dann die Zeit noch reicht, ist ja eine 
ganz andere Frage...
Gruß Rainer

von Bernhard S. (bernhard)


Lesenswert?

Rainer V. schrieb:
> also jetzt willst du wieder zanken :-) nichts wird schwieriger...du mußt
> nur mehr "push/pull" machen!

Vielleicht reden wir aneinander vorbei.

Beispiel: Ein Register wird als Rechenregister für eine Division genutzt 
und gleichzeitig
für einen Counterüberlauf (Interrupt) bei einem Frequenzzähler.

Mitten in der Division ändert sich plötzlich ein Rechenregister durch 
einen Interrupt, die Folgen wären fatal, oder liege ich da falsch?

von Rainer V. (a_zip)


Lesenswert?

Bernhard S. schrieb:
> Mitten in der Division ändert sich plötzlich ein Rechenregister durch
> einen Interrupt, die Folgen wären fatal, oder liege ich da falsch?

Ich fürchte ja. Wie gesagt, wenn du in der I-Routine mit Regs arbeitest, 
die du auch in anderen Programmteilen nutzt, dann mußt du die Inhalte 
natürlich sichern und hinterher wieder zurückschreiben. Wie sollte das 
denn sonst gehen? Das alles wird doch erst interessant, wenn du "keine 
Zeit mehr hast" und/oder wirklich alle Register schon nutzt. Also vor 
lauter Push/Pull zu nichts anderem mehr kommst! Und spätestens dann muß 
man natürlich das Gesamtwerk kritisch prüfen :-)
Gruß Rainer

von Carsten-Peter C. (carsten-p)


Lesenswert?

Bernhard S. schrieb:
> Mitten in der Division ändert sich plötzlich ein Rechenregister durch
> einen Interrupt, die Folgen wären fatal, oder liege ich da falsch?

Hallo,
jeder mag da seinen eigenen Programmierstiel für sich finden. Alle 
werden ihre Vorteile haben. Ich selbst sorge meistens dafür, dass nach 
einer ISR alle Register wieder hergestellt werden. Die unteren Register 
nutze ich gerne für Variablen, die sich häufig ändern und nicht z.B. 
über i2c abfragbar sind. Ich schreibe gerne in Blöcken, wobei ich jeden 
Block genau teste. Nach jedem Block sind alle oberen Register frei 
verfügbar und können beliebig geändert werden. Alle Variablen sind dann 
im SRAM abgelegt.

Beispiel:
UARTlesen:    ;USART lesen
  pushw x
  push R16
  in R16,SREG
  push R16
  push R17

;hier Deine Verarbeitung

  pop  R17
  pop  R16
  out  SREG,R16
  pop R16
  popw x
reti

Gruß Carsten

: Bearbeitet durch User
von Carsten-Peter C. (carsten-p)


Lesenswert?

Sorry, ich glaub, ich habe jetzt erst verstanden, was Du sagen wolltest. 
Eine Möglichkeit ist, mit Soll – Ist - Werten zu arbeiten. In der ISR 
legst Du die Sollwerte fest und später im Hauptprogramm reagierst Du mit 
den Ist – Werten.
Gruß Carsten

Beitrag #6665788 wurde von einem Moderator gelöscht.
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.