PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Wurzel Nachkommastellen als BCD...?



Jaecko
22.06.2007, 18:31
Moin...

Das folgende Programm soll aus einer Zahl, die an Port 0 eingegeben wird, die Wurzel berechnen, die Vorkommastellen in den Speicherbereich 70-72 schreiben, die ersten 5 Nachkommastellen in den Speicherbereich 73-77.

Die Wurzel berechnen klappt soweit. Die Zahl vor dem Komma wird auch korrekt eingetragen. Nur bei den Nachkommastellen hab ich irgendwie ein Problem, welches sich in einem riesigen '?' offenbart.

Im Register 2 werden ja die Vorkommastellen binär gespeichert. im Register R0 'anscheinend' der "Rest". Nur wie krieg ich diesen Rest dann als BCD-Nachkommastellen hin? Irgendwo hab ich nen Denkfehler...

(CPU ist ein normaler 8051, KEIL-Compiler)



ISEG AT 70H
ErgebnisBCD: DS 3
ISEG AT 73H
ErgebnisBCDKomma: DS 5
CSEG AT 0

;NUMH = R0
;NUML = R1
;SQRT = R2
;SUB = R3
;CNTR = R4

;WURZEL BERECHNEN
init: MOV R0,#0
MOV R1,P0
MOV R2,#0
MOV R4,#4
BCK: MOV A,R2
CLR C
RLC A
SETB C
RLC A
MOV R3,A
CLR C
MOV A,R1
RLC A
MOV R1,A
MOV A,R0
RLC A
MOV R0,A
CLR C
MOV A,R1
RLC A
MOV R1,A
MOV A,R0
RLC A
MOV R0,A
CLR C
SUBB A,R3
JC Skip
MOV 0,A
SKIP: MOV A,R2
CPL C
RLC A
MOV R2,A
DJNZ R4,BCK


;AB HIER AUFLÖSEN NACH BCD, VORKOMMAANTEIL
BCDStart: MOV R1,#(ErgebnisBCD+2)
MOV R5,#3
MOV A,R2
BCDLoop1: Call BCDDiv10
MOV @R1,B
DEC R1
DJNZ R5,BCDLoop1
JMP BCDStartNext
BCDDiv10: MOV B,#10
DIV AB
RET
BCDStartNext: MOV A,#0
MOV R1,#(ErgebnisBCD+2)
ADD A,@R1
DEC R1
ADD A,@R1
DEC R1
ADD A,@R1

;AB HIER AUFLÖSEN NACH BCD, DEZIMALSTELLEN

[...?...]


JMP INIT

ENDE:
JMP ENDE
END

Torr Samaho 2
27.06.2007, 10:35
Hallo,
ich bin nicht mehr so fit in Assembler. Deswegen seh ich bei dem Programm auf Anhieb nicht durch. Wird die Wurzel über einen "Spezialbefehl" oder von dir Rekursiv ermittelt?
Funktion einer Division:
10/2=5 Rest 0,
10/3=3 Rest 1,
Der Rest lässt sich auch als BCD weiter darstellen, aber nicht weiter teilen.
Ist im letzten Fall eben 1, bedeutet Nachkomma = 1/3.
mfg
Torr Samaho 2

Jaecko
27.06.2007, 10:47
Assembler ist eigentlich auch überhaupt nicht mein Bereich; eher Bascom, da wärs dann nur 1 Zeile; aber geht hier in dem Fall nicht.

Und mit Nachkommastellen hatt ich in ASM noch nie zu tun.

Den Wurzelalgorithmus selbst hab ich aus nem anderen Programm raus.
Er geht über die Bereiche Init, Bck, Skip. Es ist zwar etwas anders wie das iterative babylonische Wurzelziehen*, aber trotzdem funktionierts ja auch.
Dabei wird das Ergebnis der Wurzel problemlos berechnet.
Nun soll halt nur noch der Rest in R0 - sofern Möglich - als Nachkommastellen zerlegt werden.

*) Dieses war zuerst geplant, schied aber auch wegen dem Problem der Nachkommastellen in der Berechnung aus.

Jeder andere Algorithmus, der die Wurzel auf 5 Nachkommas genau kann wär auch ok. Muss nicht exakt der vorgegebene sein.

Torr Samaho 2
27.06.2007, 11:05
Da kann ich dir leider nicht helfen.
mfg
Torr Samaho 2

PICture
27.06.2007, 11:48
Hallo Jaecko!

Ich weiss nur algemein, dass wenn man die Zahl, aus der 2-er Wurzel berechnet wird, um gerade Zahl Nullen (2n) am Ende erweitert (also multiplieziert durch 100, 10 000 u.s.w.), dann wird der Wurzel mit mehr Stellen berechnet und man muss das Komma entsprechend um n Stellen nach links verschieben. Der Rest bleibt unbenutzt. Ich habe das selber nicht programmiert, Du kannst aber probieren.

MfG

Jaecko
27.06.2007, 11:57
Hm... die Idee ist nicht schlecht.
D.h. ich müsste für 5 Nachkommastellen einfach 10 Nullen anhängen. Jetzt nur noch versuchen, das in Assembler hinzukriegen... Der 8051 kann ja nur 8 Bit. Bei ner max. Eingabezahl von 255, mit 10 Nuller... rechnerisch hätt ich da dann 42 Bit... 36 zu viel => nächstes Problem...

PICture
27.06.2007, 12:28
Na ja, ich bin jetzt leider PIC benutzer aber es ist wahrscheinlich auch beim 8051 möglich aus 6 8-bittigen ein 48-bittiger Register zu erstellen.

Ich habe es so gemacht, dass ich einfach z.B. beim addieren zwei "grossen" register dass in Schritten (Schleife) mache mit berücksichtigung des Überlaufs, den ich zwischenspeichere und danach bei nächster Addition addiere. Es sieht so aus:

Register A besteht aus A5 (MSB), A4, A3, A2, A1 und A0 (LSB)
Register B besteht aus B5 (MSB), B4, B3, B2, B1 und B0 (LSB)

Die Addition:
Flag = 0
Flag + A0 + B0 = A0 --> C(Überlauf) --> Flag
Flag + A1 + B1 = A1 --> C --> Flag
Flag + A2 + B2 = A2 --> C --> Flag
Flag + A3 + B3 = A3 --> C --> Flag
Flag + A4 + B4 = A4 --> C --> Flag
Flag + A5 + B5 = A5 --> C --> Flag
Flag + A6 + B6 = A6 --> C --> Fehler

Änlich kann man Substraktion realisieren. Multiplikation realisiere ich durch mehrfache Additionen und Dividieren durch mehrfache Substraktionen.

MfG

schos
04.07.2007, 10:41
Hallo Jaecko!

Hast du dein Problem schon lösen können? Ich habe nämlich ein ähnliches Problem und mich würde interessieren wie du deins gelöst hast!

Jaecko
04.07.2007, 10:45
Moin.

ne.. leider garnix. Mehr als die Zahl vorm Komma geht nicht.
Das mit den 0er anhängen wäre zwar schon was brauchbares, aber Problem eben wie gesagt, dass die Zahlen da zu gross werden.
Das jetzige Anpassen des Wurzelziehens erschlägt einen dann mit Aufwand.