16 Bit Division auf 8051

#5126834
Lesenswert?

Hallo zusammen!

Ich müsste für ein AVR-Flash-Pages-Programmier-Programm die Anzahl Pages 
ermitteln. Dafür muss ich eine 16-Bit-Zahl (Programmgröße) durch eine 
8-Bit-Zahl (32 Page-Bytes) teilen.

Dieser Mikrocontroller unterstützt leider keine 16-Bit-Division.
Zu meinem Entsetzen musste ich feststellen dass eine 16-Bit-Division in 
Assembler sehr kompliziert ist und möglicherweise mein mathematisches 
Verständnis übersteigt.

Ist es wirklich nötig ein umfangreiches Programm mit Schiebereien und 
Schleifen mit diversen Registern zu verwenden ? Dummerweise scheine ich 
die Funktion dieses Programms nicht zu verstehen sodass ich wohl Fehler 
nicht erkennen werde...
#5126850
Lesenswert?

Hallo,

spätestens hier solltest Du den Einsatz einer vernünftigen 
Programmiersprache in Betracht ziehen, in C51 gibt es sicherlich solch 
eine einfache Division.

Üblicherweise schreibt kein effizient arbeitender Programmierer seine 
Divisionen selbst sondern er setzt fertige Bibliotheken ein. So was gab 
es früher (als ich noch mit dem 8031 gespielt habe) als 
Laufzeitbibliotheken oder als Makrobibliotheken.

Gruß,
Michael
Gast #5126925
Lesenswert?

Entschuldigung, es muss eine 16-Bit-Zahl durch 64 dividiert werden, da 
eine Page 32 Wörter (=64 Byte) hat.

Also soll ich wohl eine gegebene 16-Bit-Zahl 6 mal nach rechts schieben 
?
Es wird nichts links wieder reingeschoben nehme ich an.
Was rechts rausgeschoben wird das lasse ich einfach weg ?


Ich benötige sowieso nur das Ergebnis das vor dem Komma steht, das 
inkrementiere ich um 1 und habe damit den Schleifenzähler-Startwert für 
die Page-Programmier-Schleife.


Und ich bin gerade in purem Assembler unterwegs, eine Hochsprache kommt 
nicht in Frage.
#5126937
Lesenswert?

Warum um 1 inkrementieren?

Wenn Du korrekt runden willst, d.h. angefangene Pages sollen mitgezählt 
werden, musst Du VOR der Division die Pagegröße -1 zum Ausgangswert 
hinzuaddieren, in Deinem Fall dann also den Wert 63. Natürlich eine 16 
bit addition.

Anzahl_Pages = (Größe+63)>>6

Was links reingeschoben wird hängt von der Operation ab. Kenne den 8051 
nicht, aber auf anderen CPUs gibt es genau zwei verschiedene 
Operationen:

SHIFT RIGHT: Schiebt die Bits eins nach rechts, das oberste Bit wird auf 
0 gesetzt

ROTATE RIGHT: Schiebt die Bits eins nach rechts, das oberste Bit wird 
aus einem der CPU-Flags gefüllt (z.B. Carry), danach landet das rechts 
rausgeschobene bit in diesem Flag

(analog dazu gibt es die gleichen Befehle für LEFT)
#5126974
Lesenswert?

Markus M. schrieb:
> Warum um 1 inkrementieren?
>
> Wenn Du korrekt runden willst, d.h. angefangene Pages sollen mitgezählt
> werden, musst Du VOR der Division die Pagegröße -1 zum Ausgangswert
> hinzuaddieren, in Deinem Fall dann also den Wert 63. Natürlich eine 16
> bit addition.
>
> Anzahl_Pages = (Größe+63)>>6

Hä? Beides liefert doch das gleiche Ergebnis!

Wenn der Programmcode 15 Bytes hat, ist nach dem Schieben das Ergebnis 0 
aber es muß eine Page (+1) Programmiert werden.
Deine Rechnung mit dem +63 ergibt 78 und nach dem Schieben ebenfalls 1 
Page.
#5126992
Lesenswert?

Route 6. schrieb:
> Hä? Beides liefert doch das gleiche Ergebnis!

Nicht ganz.
Bei einer durch 64 teilbaren Programmgröße ergibt die Berechnung von 
Markus die richtige Pageanzahl, bei dem +1 Increment dagegen eine Page 
zuviel.

Beispiel: 128 Byte Programmgröße

(128 + 63) >> 6 = 191 >> 6 = 2

Dagegen:

(128 >> 6) + 1 = 3

Bei nicht durch 64 ganzzahlig teilbaren Programmgrößen ergibt sich 
dagegen dasselbe Ergebnis.

Viele Grüße, Stefan
#5127236
Lesenswert?

Peter D. schrieb:
> Anbei mal die 16Bit Division.

Peter war schneller (aber ich mußte auch erst mal wieder alte Sourcen 
durchforsten und ein Setup für MCS-51 machen, weil auf meinem Rechner 
kein MCS-51 Assembler mehr installiert war).

Und: natürlich ist Peters Version wieder kürzer und deswegen poste ich 
meine nicht.

Abgesehen davon, dass beim Problem des TO ein Ergebnis mit 
Schiebeoperationen besser zustande kommt !

-----------------------

Btw: Daraus soll ein MCS-51 basierender Flasher für AVR Controller 
herausspringen ?
#5127279
Lesenswert?

Ich sehe gerade ein mögliches Problem bei der Addition von 63 zum 
16-Bit-Wert:

Das sind doch die rechtesten 6 Bit, die da gesetzt werden. Aber diese 
werden doch dann beim 6 mal rechtsschieben einfach rausgeschoben.



Ich brauche wohl eine andere Logik, um den Schleifenzähler richtig mit 
der Anzahl Pages zu laden (angefangene Pages sollen aufgerundet werden). 
Die 6-mal-rechtsschieben-Methode sollte dabei verwendet werden, also 
keine volle 16-durch-8-Division mit allem Schnickschnack.
#5127305
Lesenswert?

Helmut L. schrieb:
> H-G S. schrieb:
>> Das sind doch die rechtesten 6 Bit, die da gesetzt werden. Aber diese
>> werden doch dann beim 6 mal rechtsschieben einfach rausgeschoben.
>
> Es gibt aber einen eventuellen Ueberlauf in Bit No7.

Wenn ich zu 64 die Zahl 63 addiere gibt es keinen Überlauf.
Nach 6 mal rechtsschieben kommt 1 heraus.

Wenn ich zB. zu 42 die Zahl 63 addiere kommt etwas größeres als 64 
heraus (aber kleiner als 128), also kommt nach 6 mal rechtsschieben auch 
1 heraus.

Wenn ich zu 128 die Zahl 63 addiere und 6 mal rechtsschiebe kommt 2 
heraus.

Bei 129 kommt 3 heraus.


Das klingt ja als wäre es in Ordnung  :-)
#5127395
Lesenswert?

Markus M. schrieb:
> Kenne den 8051
> nicht, aber auf anderen CPUs gibt es genau zwei verschiedene
> Operationen:

Eigentlich 4.

> SHIFT RIGHT: Schiebt die Bits eins nach rechts, das oberste Bit wird auf
> 0 gesetzt

Das ist das "logische" shiften. Es gibt auch das "arithmetische" shiften 
wobei das oberste Bit sein Wert behält:
0010.1000 --> 0001.0100
1010.1000 --> 1101.0100

> ROTATE RIGHT: Schiebt die Bits eins nach rechts, das oberste Bit wird
> aus einem der CPU-Flags gefüllt (z.B. Carry), danach landet das rechts
> rausgeschobene bit in diesem Flag

...und das unterste Bit landet in den Flag. Auch hier gibt's noch die 
Variante wobei die Bits nur innerhalb vom Register durchgeschoben 
werden:
[b7 b6 b5 ... b1 b0] --> [b0 b7 b6 b5 ... b1]

Auf dem Z80 sind das die Operationen
SRA (shift right arithmatic),
SRL (shift right Logical),
RR  (rotate right) und
RRC (rotate right through Carry)
#5127425
Lesenswert?

Ich werde es schon schaffen erst 63 zu addieren und dann 6 Stellen nach 
rechts zu schieben!

Wenn nicht wird halt wieder eine Woche Fehler gesucht - wie bei dem 
grausamen letzten Unterprogramm für den Blechdosenrechner  :-)

Es war immer so aufbauend wenn man einen potentiellen Fehler fand - das 
weckte Hoffnung!

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren