PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Zahl 7500 in 4 Einzelregister teilen



Philipp83
03.05.2006, 22:16
Einen schönen guten Abend allerseits!

Ich habe leider wieder ein (hoffentlich kleines :-) ) Problem mit Assembler.
ich habe eine Zahl x in 2 registern z.b. 7500 in r17 und r18 unterteilt.
Aus dieser Variablen brauche ich jetzt aber die einzelnen zehnerstellen
in register unterteilt
z.b.
0 in r19
0 in r20
5 in r21
7 in r22

das wäre generell kein Problem, nur darf die ganze Operation des aufteilens
nicht viel mehr als sagen wir mal 1000 Taktzyklen/Schritte benötigen.

Ich komme leider auf kein schlaues kurzes verfahren.
Bitte deshalb um eure Hilfe.

mfg, Philipp

izaseba
03.05.2006, 22:55
1000 Taktzyklen/Schritte benötigen.
:-s Junge, junge, etwas viel, also ich mach das so:

zielregister leeren,

1.cp,cpc Zahl mit 1000
wenn Carry, springen zu 2
inc 1000-er Register
sub sbc Zahl 1000
spring nach 1

2. cp Zahl,100
wenn Carry,springen zu 3
inc 10-er Register
sub Zahl 100
spring nach 2

3. Genauso für 10

4. Rest in 1-er Register

Fertig

Ich hoffe, Du versehst, wie ich das meine sonst Poste ich ein Codeschnipsel

Gruß Sebastian

Philipp83
04.05.2006, 20:18
Hmm...

also das System habe ich verstanden, soweit schonmal vielen Dank!
habe noch nie das Carry bit benutzt :oops: , was sagt es denn genau aus?

Wenn die Zahl genau 1000 ist und ich mit 1000 vergleiche wird durch das cp einfach zu Schritt 2 gesprungen ohne das das tausender register inc wird oder?

Gruß, Philipp

izaseba
04.05.2006, 20:45
:-k

habe noch nie das Carry bit benutzt
Das ist schlecht, Carry -> Übertrags-flag
wenn Du 1000 mit 1000 vergleichen tust wird kein Carry gesetzt,
999 mit 1000 schon :-)
Ein Tip,
AVR-Studio vorhanden ? wenn ja schreib Dir dieses kurze Programm


ldi R16,50
ldi R17,40
vergleiche:
cp R16,R17
inc R17
rjmp vergleiche


Setze ein break bei cp und führe das Programm in Debugger aus,dabei beobachtest Du den Inhalt/Zustand von SREG und R16,R17 Registern.
Besseren Lerneffekt findest Du nirgendwo, achja, bringe in Erfahrung was Die anderen Flags in SREG zu sagen haben.
Das ganze im Zusammenspiel mit brcs brcc brsh brlo brmi usw. bringt Dir die Lösung.
Wenn immernoch nicht dann fragen, oder von Erfolgen berichten!

Gruß Sebastian

Philipp83
08.05.2006, 15:03
wie kann ich eigentlich die x,y,z register beschreiben und als 16 bit nutzen?

Ich verstehe das rechnen mit 2 registern für 1 Zahl nämlich nicht wirklich.

Ich habe schon keine ahnung wie ich 1000 (2 register) mit einer zahl die auch
in 2 registern steht vergleichen, geschweige denn abziehen kann :-(

man kann doch diese 3 register als 16 bit register nutzen und damit dann einfacher rechnen oder?

mfg, Philipp

izaseba
09.05.2006, 17:01
Du kannst keine Register als "16 Bit" nutzen alle Register sind 8 Bit breit.
X,Y,Z Register sind für die Adressierung von Ram und Flash gedacht, nicht um 16 Bit zu rechnen.
Mann kann sie zwar auch als "normale" Register nutzen, aber man sollte sie schon für die oben genannte Aufgaben belassen.



Ich habe schon keine ahnung wie ich 1000 (2 register) mit einer zahl die auch
in 2 registern steht vergleichen, geschweige denn abziehen kann




.equ eine_grosse_Zahl = 1000
ldi R16,HIGH(eine_grosse_Zahl)
ldi R17,LOW(eine_grosse_Zahl)

Hiermit hast Du die Zahl 1000 auf zwei Register aufgeteilt.
Es geht auch direkt:


ldi R16,HIGH(1000)
ldi R17,LOW(1000)


Jetzt mal angenommen in R2 und R3 steht eine Zahl drin, die Du z.B. beim AD Wandlung eingelesen hast in R2 ADCL in R3 ADCH.

Beide Zahlen vergleichen:


cp R2,R17 ; Zuerst beide Low Bytes vergleichen
cpc R3,R16 ; Jetzt beide Highs UND den Carry dazu!!!


Wenn Jetzt Carry gesetzt ist ist R2,R3 kleiner als R17,R16, sonst Größer oder gleich.
Subtraktion geht genauso nur nicht mit cp,cpc sondern mit sub,sbc.

Ich mußte früher, wo ich noch in der Schule war ohne Taschenrechner arbeiten :-( und mußte alles per Hand rechnen, es ging auch etwa in der Art.

Beispiel:



163
56 -
---------


Hier geht mal genauso vor:

Letzte Zahl:
3 - 6 geht nicht weil 3 kleiner als 6 also eine 1 vor die 3 und "Carry" Setzen
13 - 6 -> 7

Nächste Zahl:
6-5 -> 1 aber da "Carry" gesetzt war nochmal 1 ergibt 0; hier kein Carry da Ergebnis nicht negativ war.

Nächste Zahl:

1-0 -> 1 kein "Carry" bleibt also 1

Hiermit haben wir 107 erhalten.

Genauso geht es mit Rechnen über mehrere Register, es ist egal ob Du nur 2 Register hast 3,5 oder 10

Ich hoffe das war jetzt klarer.

Gruß Sebastian