DIV-Befehl

; Der Anfang, weil wir es ein mal rekursiv machen und ein mal ohne, benutzen wir einen Stack
; weil wir die Ausgab auf PORTD machen, setzen wir DDRD auf 0xff
; ich muss gucken ob ich mich mit der Reihenfolge beim Stack nicht vertan habe.
; Ja, ich habe mich vertan ich muss das umdrehen, das ist allerdings unlogisch, deswegen gucke ich noch mal nach.
; nein, ich habe mich nicht vertan, sondern bei meinem Merkblatt
; ich muss die Include file fuer das LCD einbinden, weil ich das jetzt nicht neu schreibe
; ausserdem muss ich, den RAM, weil wir haben ja einen Statischen Code, im Statischen Speicher - EEPROM - da ist unser Programm und unsere statischen Daten - allerdings koennen wir da unsere Folge nicht rein schreiben, weil die muss ja in den dynamischen Speicher RAM - anders als Bei x86, wo der RAM vorherrscht und - ich moechte einfach die Quadratzahlen ausgeben, im RAM bei Daten, nennt das Heap - (1.) statische Daten, Programm (2.) Stack (3.) Heap Dynamische Daten, speichern (4.) Bereich fuer die EA
; Also, den haep mache ich mit dem Label .data leite ich das ein und davor normal das label fuer das Variablen Namen, ich verwende jetzt allerdings fuer die groesse, der Speicherbereiche nicht DB usw. sondern BYTE, bei AVR Spezifisch
; ich muss natuerlich die numbers in zeichen umwandeln, aber das duerfte kein Problem sein, habe ich neulich auf x86 gemacht und immer durch 10 teilen, bis nichts mehr da ist und der Rest + '0' ist jeweils das Auszugebende zeichena

.include "m8def.inc"

.def temp1 = r16
.def temp2 = r17
.def temp3 = r18

ldi r16, HIGH (RAMEND)
out SPH, r16
ldi r16, LOW (RAMEND)
out SPL, r16

ldi r16, 0xff
out DDRD, r16

ldi r16, 5
mul r16, r16
mov r17, r0
; so erst mal die quadratzahlen speicher speichern
ldi ZH, HIGH (squarenumbers)
ldi ZL, LOW (squarenumbers)
ldi r16, 1
; jetzt muss ich den mul fuer AVR nachschauen
; https://cdn-reichelt.de/documents/datenblatt/A300/ATMEGA8xxx.pdf
; MUL Rd, Rr Multiply Unsigned R1:R0 ← Rd x Rr
loop1:
mul r16, r16
st Z+, r0
inc r16
cp r16, r17
brne loop1

;jetzt probiere ich mal aus, ob sich der Code schon mal uebersetzen laesst.

;Da kommt unknown Direktive Data. Ich schaue im Buch nach.

;ich habe unsinn gebaut, das heisst .dseg natuerlich, das war dummheit.

.dseg

squarenumbers: .byte 10

.include "lcd-routines.asm"
jetzt probiere ich mal aus, ob sich der Code schon mal uebersetzen laesst. Da kommt unknown Direktive Data. Ich schaue im Buch nach. ich habe unsinn gebaut, das heisst .dseg natuerlich, das war dummheit.
; Der Anfang, weil wir es ein mal rekursiv machen und ein mal ohne, benutzen wir einen Stack
; weil wir die Ausgab auf PORTD machen, setzen wir DDRD auf 0xff
; ich muss gucken ob ich mich mit der Reihenfolge beim Stack nicht vertan habe.
; Ja, ich habe mich vertan ich muss das umdrehen, das ist allerdings unlogisch, deswegen gucke ich noch mal nach.
; nein, ich habe mich nicht vertan, sondern bei meinem Merkblatt
; ich muss die Include file fuer das LCD einbinden, weil ich das jetzt nicht neu schreibe
; ausserdem muss ich, den RAM, weil wir haben ja einen Statischen Code, im Statischen Speicher - EEPROM - da ist unser Programm und unsere statischen Daten - allerdings koennen wir da unsere Folge nicht rein schreiben, weil die muss ja in den dynamischen Speicher RAM - anders als Bei x86, wo der RAM vorherrscht und - ich moechte einfach die Quadratzahlen ausgeben, im RAM bei Daten, nennt das Heap - (1.) statische Daten, Programm (2.) Stack (3.) Heap Dynamische Daten, speichern (4.) Bereich fuer die EA
; Also, den haep mache ich mit dem Label .data leite ich das ein und davor normal das label fuer das Variablen Namen, ich verwende jetzt allerdings fuer die groesse, der Speicherbereiche nicht DB usw. sondern BYTE, bei AVR Spezifisch
; ich muss natuerlich die numbers in zeichen umwandeln, aber das duerfte kein Problem sein, habe ich neulich auf x86 gemacht und immer durch 10 teilen, bis nichts mehr da ist und der Rest + '0' ist jeweils das Auszugebende zeichena

.include "m8def.inc"

.def temp1 = r16
.def temp2 = r17
.def temp3 = r18

ldi r16, HIGH (RAMEND)
out SPH, r16
ldi r16, LOW (RAMEND)
out SPL, r16

ldi r16, 0xff
out DDRD, r16

ldi r16, 5
mul r16, r16
mov r17, r0
; so erst mal die quadratzahlen speicher speichern
ldi ZH, HIGH (squarenumbers)
ldi ZL, LOW (squarenumbers)
ldi r16, 1
; jetzt muss ich den mul fuer AVR nachschauen
; https://cdn-reichelt.de/documents/datenblatt/A300/ATMEGA8xxx.pdf
; MUL Rd, Rr Multiply Unsigned R1:R0 ← Rd x Rr
loop1:
mul r16, r16
st Z+, r0
inc r16
cp r16, r17
brne loop1

;jetzt probiere ich mal aus, ob sich der Code schon mal uebersetzen laesst.

;Da kommt unknown Direktive Data. Ich schaue im Buch nach.

;ich habe unsinn gebaut, das heisst .dseg natuerlich, das war dummheit.

.dseg

squarenumbers: .byte 10

.include "lcd-routines.asm"
und ein kleiner fehler war drin, ich habe ld statt ldi verwendet. So im naechsten schritt, wandle ich die zahlen in die richtigen ziffern und zeichen um, dann kann ich schon ausgeben.

jetzt hat der AVR natuerlich keinen DIV Befehl, dann muss ich jetzt entweder dividieren binaer oder mir was anderes ausdenken

binaer multiplizieren geht so

1101 * 1010

1101 * 1000
+
1010 * 10
Das geht auch mit Shiften jeweils, hinter die Division bin ich bisher auch beim Abakus noch nicht dahinter gekommen, aber wir koennen ja mal ueberlegen.

Wenn ich das umkehre und 1010 das glaube ich zufaelligerweise 10dec

dann muss ich die Subtraktion umkehren, das heisst, das Ergebnis ist die summe von allen.

x * 10 + x * 1000 = y

Ich mus diese gleichung loesen.

jetzt muss ich das aber umstellen

(y - x*1000)/x = 10

oder so. muss ich kurz nachdenken.

man koennte jetzt ein horner schema verwenden und x ausklammer, oder 10 ausklammen

x * (10 + 1000)
x* 10 * (1+100)
muss kurz ueberlegen

wir koennten ein intervallhalbirungsverfahren anwenden. Um die Gleichung

x * 10 + x * 1000 = y
zu loesen kann ich lauter x einsetzen und das im Intervallhalbierungsverfahren

oder jetzt faellt mir auf -

wir haben es schlussendlich mit einem polynom zu tun. wir

1010 haben

ist der Faktor 0 * x2 und 0*x0

aber sonst steht x fuer 10
dann haben wir, eigentlich haben wir eine Mischung aus einer linearen Gleichung und einer Polynogleichung, weil wir haben die Potenzen bei 10

10^0
10^1
...

aber es ist eine lineare

Mal gucken, wenn wir die Potenzen anwenden, kriegen wir es vielleicht hin

doch doch, wir koennen ohne problem durch 10, 100, 1000 teilen, das sind jeweils shifts nach links, 2 bit, 3 bit, 4 bit

Dann schreiben wir das einfach mal so hin
c
x * 10 + x * 1000 = y

x << 2 + x << 1000 = y
Dann koennen wir die gleichung jetzt vielleicht so umdrehen,
y >> 1000
vielleicht ist ja das die loesung
y >> 10 - y >> 1000 = x
ausprobieren in c

ich glaube ich habe eine gewisse Loesung, man muss nich folgendes machen

x1 - x2 - x3 ...
wenn sie das jetzt vorstellen
x3 = x5-x4
egal, jetzt muessen differenzen von hinten bilden und dann jeweils vom groesseren die differenz abziehen und vom naechstgroesseren wieder die Differenz.

#include <stdio.h>

int main (void) {
    int a = 212;
    int b = 314;
    int y = a*b;
    int x;
    int x0, x1;
    int i;

    printf ("%i\n", y);

    for (i = 0, x0 = 0;  i < 14;  i++) {
        if (((a >> i) & 0x01)) {
            x0 = (y >> i);
            break;
        }
    }
    for (;  i < 14;  i++) {
        if (((a >> i) & 0x01)) {
            x1 = (y >> i);
            x0 = x0 - x1;
            printf ("x1: %i, i: %i, x0: %i ", x1, i, x0);

        }
    }
    printf ("%i\n", x0);

return 0;
}

Nein, das ist nur eine moeglichkeit

aber, wenn man hat

5 - 3 - 1 ist das 1
und (5 - (3-1) ist drei.
Was unlogish waere weil, dann wuerde die zahl groesser.

aber wir koennten auch von der groesseren zahl die naechste abziehe

x1-x2
und von x2 x1 und zu dem von vorher, das abziehen

oder so, ich weiss es nicht

aber in der Umkehrung der Formel

x << 1000 + x << 10 = y
liegt die Loesung.

Wir muessen jetzt versuchen dafuer einen mathematischen Koerper fuer die ganzen zahlen zu finden, um es so um zu drehen.

Also

x << 1000 + x << 10 = y

(x << 100 + x) << 10 = y

(x << 100 + x) = y >> 10
jetzt kann ich x ausklammern
x * (1 << 100 + 1) = y >> 10
x = (y >> 10) / (1 << 100 + 1)
ja, hier weiss ich niht witer, wegen eben dem Shift

aber, was ich viellecht das selbe wie gerade ebe

x = (y * 10)/(101)
Da weiss ich eben nicht weiter.

einen moment wir haben zeit.

Nein, man kann die gleichung

x*1000 + x*10 = y
fuer x nicht einfach loesen. Weil, anders herum, wenn x fest ist, ist das kein Problem, aber x taucht mehrfach auf

was man tun koennte, waere

Das Ergebnis - x*1000 = y ausrechnen
x * 10 = y
nach x aufloesen, also, fuer ein festes y und daraus einen geschickten Mittleren wert errechnen.

fuer 1000 kann ich das nach links shiften, das y. Kann ich 4 nach links shiten

natuerlich heisst das x << 4 fuer x * 1000 und nicht x << 1000, aber das ist jetzt egal.

ich glaube ich habe einen loesungsansatz

1010 * x = y
1000 * x + 10 * x = y
10 * (100*x + 1*x) = y
(100*x+1*x) = y/10
So, jetzt ist
101 * x = y/10
ok, das ist trivial

aber jetzt muss ich ausrechnen

y/10/101
und so weiter.

So wuerde ich das verfeinern, jetzt habe ich nur das Problem, mit der 1 bei der 101

das ist das problem

also, ich muesste quasi immer weiter teilen und dabei muesste die 1 am Ende, etwas bewirken.

ich muss quasi einen bestimmten fall einfuehren durch

10
100
1000
10000
100000
kann ich ohne problem teilen ich kann durch 10000 teilen indem ich durch
100 100 teile, zwei mal
ich brauche jetzt den spezialfall
101
1001
10001
100001

...
wenn ich den loesen kann, dann kann ich das Ergebnis ausrechnen, zwischenspeichern, und jedes Mal den Fall erneut anwenden.

ich habe einen algorithmus, der mit wenigen schritten, mit wenig subtraktionen und ich sage, das ist erlaubt, weil es gibt Hardware algorithmen, die werden in ASM Diagrammen und - RTL genommen. Sie koennen fuer die Multiplikation, eine schleife von additionen machen. Aber wie man 10001 ausrechnet Also

y = x * 10001
So, dann gilt
y = 10000 * x + x
So, ist ist die Struktur so zu sagen von
x*10000
x
quasi die gleiche, also
x0000
x
und das entspricht dem y, x0000

so, damit wissen wir, weil am ende nur eine 1 steht, keine andere Zahl, keine riesige zahl, sondern nur eine 1, der unterschied wird nicht bedeutend sein

so, dann haben wir

x0000 und y
und wir wissen, dass das von der struktur identisch ist, das ist das gleiche

wir werden also hier anfangen. Wir wissen jetzt, dass das

und anders formuliert

wir nehmen y und wir sagen, das ist x000 und jetzt nehmen wir x, das ist x000 » 000 nach da

und jetzt probieren wir aus

wenn wir das x aendern, das heisst, 1 nach unten zaehle, dann aendern wir das x000 und zwar beim x, logischerweise

dabei subtrahieren wir. und wenn das Ergebnis y ist dann stimmt es

Jetzt muessen wir bedenken fuer den Algorithmus

y/10000
ist
y/10/10/10/10
genauso mussen wir jetzt auch denken, mit einem bisschen ausprobieren. Dazwischen, weil wir stossen unterwegs wir teilen ja nicht nur
10000
immer wieder auf
101
1001
10001
Gut, wir wissen

10001 ist von 1000x nich so unterschiedlich, deswegen werden wir nicht viel zahlen

Jetzt haben wir aber bruchwerte

2/3
Das machen wir natuerlich nicht, da bleibt ein Rest. Und da muessen wir jetzt nachdenken.

Es besteht vielleicht folgendes Moeglichkeit, wenn wir mit

100001
multiplizieren x
dann ist y = 100000 * x + x
Wenn y vorne und hinten die gleiche Struktur hat
x1,x2

x1 = x2

und x1*100000 + x2
Dann wenn das fuer y gilt, egal wie gross x ist, waere das problem schnell geloest

Jetzt zahlen wie

10101110
die struktur hinten, bei * 1000 entspricht nicht dem vorne
1010 1110
und wir koennten jetzt vielleicht mit der Differenz zwischen
1010 und 1110
etwas anfangen.

mir kommt es so vor, als haette ich eine idee

also, wenn ich

1000100011000000
durch 100 teile, dann kommt heraus
10001000110000
wenn ich das aber durch

100000000000 teile werden 1 verschluckt. Bei einer Operation nicht tragisch, das ist ein Rest. Gut, durch die Schiftung bleibt erhalten

darueber haben wir bisher nicht gesprochen.

was in dem Fall y betrifft

Gut, wenn wir

1011 0011 = y
haben und durh
1011 teilen fuer x, als Ergebnis dann ware

10001 * 1011

1011 1011
so, da sagten wir, dass es her eine Differenz gibt, aber das ist ein Rest, und zwar ein positiver oder negativer

Der unterschied, zwischen dem eigentlichen Ergbenis

1011 0011

und

1011 1011
ich kann nicht genau wie genau sich das jetzt mit dem Rest verhaelt, da wir aber den Rest am Ende mitnehmen muessen, koennen wir uns ueberlegen, wenn den Rest verstanden haben, der da neu ensteht, ob wir den einfach mit einbauen.

ich meine, bei einer Ganzzahl division bleibt so oder so ein Rest

dann sage ich einfach jetzt das Ergebnis, ich muss mal ausprobieren, Rest irgendetwas. Was da raus kommt, jetzt mal ueberpruefen. es sieht so aus, als haette es funktioniert.

Also

11011.01101/100001

11011.11011
-11011.01101
Ich habe zur probe, den rechner genommen
11011 * 100001 = 11011.11011
Wie zu erwarten, hat es sich bestaetigt

Jetzt

11011.11011 - 11011.01101 = 1110

Also sind 11011.01101/100001 = 11011 Rest 1110
Und das Ergebnis im Dec ist
877

und 27*33-14 = 877

Gut, unterschied, positive und negative Reste

Den Rest muessen halt mitnehmen und dann koennen wir weiter machen. ich glaube wir sind der Sache sehr nahe und ich mache Beendet fuer heute. Es bietet sich dann die Reste zu addieren, das heisst, mitzu nehmen, und dabei wird die Potenz an 10, mit der reste vergrossert, immer groesser. oder umgekehrt. Am ende bleibt ein groesserer rest, ich vermute, den kann ich wieder so telen und addiere. Warum addieren? Weil Rest ist immer dazu addiert, irgendwann ist der Rest kleiner, als der Divisor. Wenn er das ist, dann ist das der Rest, der sich nicht mehr laesst.