- LiTime Speicher und Akkus         
Ergebnis 1 bis 10 von 10

Thema: Rechnen mit 3 Registern

  1. #1
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    02.02.2005
    Ort
    Hamburg
    Alter
    40
    Beiträge
    176

    Rechnen mit 3 Registern

    Anzeige

    Powerstation Test
    Einen schönen guten Abend erstmal !

    Also ich habe eine Zahl in 3 Registern ( 5000000 )
    möchte diese nun durch die in 2 Registern stehende ( 36500)
    teilen. Es sollte 136 rauskommen.

    Aber wie kann ich Binär eine Zahl die in 3 Registern steht,
    durch eine andere die in 2 Registern steht teilen?


    Es wäre wirklich super !!! wenn mir einer die vorgehensweise erläutern kann


    mfg, Philipp

  2. #2
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.802
    Eigentlich nimmt man da "Schuldivision" (wie man sie in der Grundschule lernt).

    Kommt darauf an, in welcher Sprache du das formulieren willst... oder willst du eine algerbraisch formale Beschreibung???
    Disclaimer: none. Sue me.

  3. #3
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    02.02.2005
    Ort
    Hamburg
    Alter
    40
    Beiträge
    176
    Naja, mir ist der ganze logische Ablauf nicht so ganz klar

    Was muss ich mit welchem register in welcher Reihenfolge machen und was gibt es im uC vielleicht für fertige befehle dafür?

  4. #4
    RN-Premium User Begeisterter Techniker
    Registriert seit
    30.04.2004
    Alter
    46
    Beiträge
    245
    Hallo Philipp,

    das ist beim AVR nur mit guter Handarbeit zu erledigen. Hab mal eben ein Muster zusammengeschusselt, ich denke es sollte funktioneren - aber vorher unbedingt testen - ich will nicht schuld sein, wenn deine Bombe zufrüh hochgeht weil die Rechnung nicht stimmt :-D

    .def rd1hh=r16
    .def rd1h=r17
    .def rd1l=r18
    .def rd2h=r19
    .def rd2l=r20
    .def rd1ul=r21
    .def rd1uh=r22
    .def rehh=r23
    .def reh=r24
    .def rel=r25

    div:
    ldi rd1hh, 0x4c
    ldi rd1h, 0x4b
    ldi rd1l, 0x40

    ldi rd2h, 0x8e
    ldi rd2l, 0x94

    clr rd1ul ;Hilfsregister
    clr rd1uh

    clr rehh ; Ergebnis rehh:reh:rel
    clr reh ;
    clr rel ; (Ergebnisregister dient auch als
    inc rel ; Zähler bis 24! Bit 1 auf 1 setzen) diese 1 wird immer weiter nach links geschoben, wenn sie
    ; rauskommt sind wir fertig
    ;
    ; Hier beginnt die Divisionsschleife
    ;
    div1:
    clc ; Carry-Bit leeren
    rol rd1l ; nächsthöheres Bit des Dividenten
    rol rd1h ; in das Hilfsregister rotieren
    rol rd1hh ;
    rol rd1ul ;
    rol rd1uh ;
    brcs div2 ; Eine 1 ist herausgerollt, ziehe ab

    cp rd1uh, rd2h
    brcs div3
    cp rd1ul,rd2l ; Divisionsergebnis 1 oder 0?
    brcs div3 ; Überspringe Subtraktion, wenn kleiner
    div2:
    sub rd1ul,rd2l ; Subtrahiere Divisor
    sbc rd1uh,rd2h
    sec ; Setze carry-bit, Ergebnis ist eine 1
    rjmp div4 ; zum Schieben des Ergebnisses
    div3:
    clc ; Lösche carry-bit, Ergebnis ist eine 0
    div4:
    rol rel ; Rotiere carry-bit in das Ergebnis
    rol reh
    rol rehh
    brcc div1 ; solange Nullen aus dem Ergebnis
    ; rotieren: weitermachen


    Zum erklären: am besten AVR Studio runterladen (vielleicht hast dus ja schon) und simulieren und beobachten - dann verstehen versuchen.
    Im Prinzip schiebt man die 5000000 nach links raus in 2 Hilfsregister und schaut, ob man davon schon die 36500 abziehen kann. Wenn ja, ins Ergebnis eine 1 schieben sonst eine 0. Ein Sonderfall kann eintreten, nämlich das beim Hilfsregister auch eine 1 rauskommt. Die kannst du dann gleich ins Ergebnis schieben.
    Wie gesagt, simulieren und studieren, dann klappts auch mit dem Assembler .
    Das ganze oben ist natürlich jetzt ziemlich roh, in eine Unterroutine verpackt kannst du da noch einige Register einsparen (push / pop) werte aus dem Ram holen etc. Mußt dir halt eine gute Schnittstelle überlegen je nach Anwendung.

    Was wirds wenns fertig ist?

    lg

    Alex

  5. #5
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.802
    Vom Prinzip her ist die Vorgehensweise so, wenn man quot = a / b und mod = a modulo b berechnen will:
    1. Erweitere b zu einem 24-Bit-Wert, indem man es expandiert. Wie expandiert wird, ist abhängig davon, ob die Werte Vorzeichen haben oder nicht. Ist b ohne Vorzeichen (also >= 0) wird es mit Nullen aufgefüllt. Ist b vorzeichenbehaftet, wird das obere Bit von b zum Füllen verwendet
    2. Merke die Vorzeichen ersetzte a, b durch ihre Beträge
    3. Falls b=0 dann FEHLER
    4. Falls b > a oder a=0 dann quot:=0, mod=:a, Gehe zu 12.
    5. mask:=1, quot := 0
    6. Schiebe mask und b so lange nach links, bis das obere Bit von b mit dem oberen Bit von a übereinstimmt
    7. Falls b<=a dann a := a-b, quot := quot OR mask
    8. Schiebe b und mask um 1 nach rechts
    9. Falls b ungleich 0 dann gehe zu 7.
    10. mod := a
    11. Rechne die gemerkten Vorzeichen von a und b in das Ergebnis ein
    12. Fertig


    Von a werden also 2er-Potenzen von b abgezogen, falls dieser Wert <= a ist. Wie hoch die Potenz ist merkt mask. Im Falle einer Subtraktion wird zum Ergebnis mask addiert (in diesem speziellen Fall geht ein OR (bitweise ODER), gleichbedeutend und gleicheffizient für AVR ist eine Addition).

    Linksschieben geht mit
    add R0, R0
    addc R1, R1
    addc R2, R2
    ...
    Für addc x, x ist auch die Abkürzung rol x gebräuchlich, für add x, x auch lsl x oder asl x

    Zum Vergleichen nimmt man
    cp A0, B0
    cpc A1, B1
    cpc A2, B2
    ...
    cp und cpc funktionieren genauso wie Subtraktion, nur das A nicht verändert wird, sondern nur die Flags, Mit dem Carry-Flag kann man auf größer/kleiner testen, mit dem Zero-Flag auf Gleichheit, etc
    Disclaimer: none. Sue me.

  6. #6
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    02.02.2005
    Ort
    Hamburg
    Alter
    40
    Beiträge
    176
    habe grad ein problem mit dem obigen programm:

    und zwar müsste doch beim dividieren von EA60 / 1388 also:
    rd1hh: 0x00
    rd1h: 0xEA
    rd1l: 0x60

    rd2h: 0x13
    rd2l: 0x88

    das Ergebnis C rauskommen oder?

    es kommt aber nur 4 raus.

    Ist das obige programm falsch?????

    BITTE UM SCHNELLE HILFE !!!

  7. #7
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.802
    Jaja, offenbar. Das Ergebnis ist wie gesagt 0xc.
    Disclaimer: none. Sue me.

  8. #8
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    02.02.2005
    Ort
    Hamburg
    Alter
    40
    Beiträge
    176
    UPS, ich meinte auch nicht 1888 sondern 1388.

    dabei kommt ein falsches ergenbnis raus

  9. #9
    RN-Premium User Begeisterter Techniker
    Registriert seit
    30.04.2004
    Alter
    46
    Beiträge
    245
    Ja, da war ein Fehler drinnen.
    cp rd1uh, rd2h
    brcs div3
    cp rd1ul,rd2l ; Divisionsergebnis 1 oder 0?
    brcs div3 ; Überspringe Subtraktion, wenn kleiner
    div2:
    ist natürlich topfen....

    cp rd1ul,rd2l ; Divisionsergebnis 1 oder 0?
    cpc rd1uh, rd2h
    brcs div3 ; Überspringe Subtraktion, wenn kleiner

    So ist es gleich viel besser.. Sorry.

    lg

    Alex

  10. #10
    Gast
    Klasse!!

    Ich danke dir vielmals!!!!!

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

LiTime Speicher und Akkus