Hallo
nach langem Kopfzerbrechen und keiner vernünftigen Lösung versuche ich
hier mein glück.
Ich denke die Frage ist kein Problem.
Ich habe 3 8Bit Register, in einem steht die 1er Zahl im nächsten die
10er Zahl und im 3. die 100er Zahl
Maximal kann aber nur 999 erreicht werden(anzeigebedingt)
Nun möchte ich diese 3 Registerwerte in einem 16Bit Register
abspeichern.
Wie kann ich das lösen?
Mein erster Gedanke waren die Pointer, aber ich weiß nicht wie!
Wer kann helfen.
Martin
Hi Martin,
hier ein Vorschlag (vielleicht nicht der eleganteste, könnte aber
funmtionieren):
1. Die Einer und die Zehner addieren (add).
2. Schauen, ob die Hunderter größer als 2 sind
--> nein --> Hunderter dazuaddieren (add) --> fertig!!!
--> ja --> siehe 3.!
3. 200 zum 1. Ziel-Register addieren (adiw)
4. 200 von den Hundertern abziehen (subi)
5. Die "übrigen" Hunderter ins 2. Ziel-Register. --> fertig!!!
Versuch's mal so und berichte, ob's geklappt hat!
Grüße,
Sebastian
Danke Sebi,
Aber kannst du mir sagen was du mit den 200 immer erreichen willst und
welches Register ist nachher da low und welches das high Byte?
Also Edi leider läßt mein 8515 keine multiplikation zu.
hast du einen Andere möglichkeit?
Martin
Jedes Byte kann max. 9 sein.
Du benötigst demnach 4 Bit pro "Byte".
Dann machs doch einfach so:
xxxxhhhh zzzzeeee
x = frei
h = hunderter
z = zehner
e = einer
das kannst Du einfach mit Schiebeoperationen und Maskierung
bewerkstelligen.
Hi Martin,
bevor ich's erklär, hier ein paar Definitonen:
.def Einer = r16
.def Zehner = r17
.def Hunderter = r18
.def Ziel_low = r28
.def Ziel_high = r29
.def temp1 = r21
.def save1 = r22
.def save2 = r30
.def save3 = r31
Nun addiertst Du zuerst Einer und Zehner (Ergebnis minimal 0 und maximal
99).
Was mir hier gerade auffällt: Vergiß das mit den 200. Denkfehler von
meiner Seite. Auch der Rest hatte Denkfehler.
Hier ein neuer Vorschlag:
; Zehner-Zahl erzeugen (Zehner*10)
mov temp1,Zehner
add Zehner,temp1
add Zehner,temp1
add Zehner,temp1
add Zehner,temp1
add Zehner,temp1
add Zehner,temp1
add Zehner,temp1
add Zehner,temp1
add Zehner,temp1
mov save3,temp1 ; hier stehen die Zehner (z.B. 6*10 = 60)
addi save3,Einer ; nun sind die Einer und Zehner addiert
; Hunderter in save1 und save2 ablegen
; zuerst x10
mov temp1,Hunderter
add Hunderter,temp1
add Hunderter,temp1
add Hunderter,temp1
add Hunderter,temp1
add Hunderter,temp1
add Hunderter,temp1
add Hunderter,temp1
add Hunderter,temp1
add Hunderter,temp1
;nochmal x10
mov save1,Hunderter
mov temp1,Hunderter
add Hunderter,temp1
add Hunderter,temp1
add Hunderter,temp1
add Hunderter,temp1
add Hunderter,temp1
add Hunderter,temp1
add Hunderter,temp1
add Hunderter,temp1
add Hunderter,temp1
; die Hunderter stehe nun in save1 (low)/save2 (high)
; der Rest immer noch in save3, also:
add save1,save3
mov Ziel_low,save1
mov Ziel_high,save2
Ich hab's nicht getestet, probier's mal!
Sebastian
Ja wie Jangomat würd ichs auch machen (heist glaub ich packed BCD). Die
AVR's kennen den Swap Befehl (vertauscht die oberen 4 bit(= 1 Nibble)
mit den unteren 4 bit eine 8 bit Registers (etwas schneller als
schieben) und dan maskieren.
Gruß Bernhard
Nun das ist nicht in meinem sinne da anschließend ein Pointer mit dem
16bit wert geladen werden soll und da ist deine Möglichkeit Jangomat
nicht ideal.
wenn beispielsweise
1er = 00000000 = 0
10er = 00000101 = 5
100er = 00000010 = 2
dann sollte mein 16 bit wert so aussehen:
00000000 11111010
HighByte LowByte
und das ist mein Problem
Martin
Also
zu Sebi ist zu sagen, dass bei dir nirgends erwähnt wird wie du
Hunderter und save1 und save 2 verarbeitest und des weiteren versuch mal
wenn Hundert = 9
dann 9x10 und anschließend nochmal die 90x10 in einem 8Bit Register zu
realisieren.
Zu den Bernhard und Jangomat ist zu sagen, vielleicht funktioniert es
wie ihr es vorhabt, nur leider kann ich mit maskieren noch nicht viel
anfangen.
Könntet Ihr eure Methode vielleicht etwas genauer beschreiben und
erklären?
Martin
Hallo,
dann mußt Du wohl wirklich von Hand multiplizieren:
Ergebnis=Einer + Zehner*0Ah + Hunderter*64h
die Multiplikation mit Additionen und Schleifenzähler nachbilden.
Braucht wenig Platz!
Hi Martin,
schon klar, ich habe gehofft, es gibt einen automatischen Überlauf ins
nächste Register, dann würd's schon klappen! Kann sein, daß es auch nur
mit den 4 obersten Registern geht, müsst ich mich auch nochmal einlesen.
Sebastian
Noch eine Frage dazu.
Würde es funktioniern wenn ich sage
X-Pointer(16bit) + Einer + Zehner + Hunderter
??
Das wäre dann nämlich die einfachste Methode.
Martin
Man kann es auch mit der Zählmethode machen, d.h die einzelnen Digits
runterzählen und dementsprechen oft 10 bzw. 100 zum Ergebnis addieren:
.def hund = r16
.def zehn = r17
.def ein = r18
.def lowbyte = r19
.def highbyte = r20
mov lowbyte, ein
ldi highbyte, 0
m1:
dec zehn
brmi m2
subi lowbyte, -10 ;+10
rjmp m1
m2:
dec hund
brmi m3
subi lowbyte, low(-100) ;+100
sbci highbyte, high(-100) ;Übertrag beachten !
rjmp m2
m3:
ret
Peter
Ich hatte dich falsch verstanden. Du willst also doch multiplizieren.
Was du machen willst ist bei deinem Beispiel X = 2 * 100 + 5 * 10 + 0.
Ich selber verwende kein asm für Mathe. Befrag mal die Suche nach
Multiplikation da gibt es reichlich Beispiele.
Gruß Bernhard
Nun gut das leuchtet mir ein.
Leider kann ich beim 8515 nicht den Befehl MUL (multiplizieren)
anwenden.
Erlich gesagt bin ich gerade genau so weit wie am Anfang.
Aber es muß doch eine Methode geben. Wenn ich beispielsweise Einer und
Zehner addiere, dann hab ich nur noch 2 x 8Bit
und jetzt müßte ich diese beiden Register (Hunderter und (Einer+Zehner)
irgendwie miteinander verknüpfen um einen 16Bit wert zu erhalten.
Das kann doch eigentlich gar nicht so schwer sein!!!!
Grübel.....
Bitte alle mithelfen
Gruß Martin
hi,
sorry fuer meine ignoranz...(es gibt keine multiplikation)
ich spiele mit dem 8051er.....aber einem ''ding'',das pro sekunde
millionen zyklen macht, dem kann man doch ein 16bit register bis zu 999
mal hochzaehlen lassen.
...oder gibt es beim AVR kein 'INC' ?
ed
long live '51