Moin, ich hab hier eine Funktion, die mit eine Division auf einem PIC ausführt und ich versuche schon den ganzen morgen zu verstehen, wie sie funktioniert. Aber irgendwie fehlt mir der richtige Anstoß. [asm] ;*********************************************************************** ****** ;divide OUT_HI_2,OUT_MI_2,OUT_LO_2 / DIV_HI_2,DIV_LO_2 and places result ;in OUT_HI_2,OUT_MI_2,OUT_LO_2, remainder REM_HI_2,REM_LO_2 ;divide by 0 = 0,in = 0 -> out = 0, Div_24x16: clrwdt clrf REM_HI clrf REM_LO movlw .24 movwf MUL_COUNTER div_24x16_1: rlf OUT_LO,F rlf OUT_MI,F rlf OUT_HI,F rlf REM_LO,F rlf REM_HI,F rlf MUL_COUNTER,F ; save carry in counter movf DIV_LO,W subwf REM_LO,F movf DIV_HI,W btfss STATUS,C incfsz DIV_HI,W subwf REM_HI,W btfsc STATUS,C bsf MUL_COUNTER,0 btfsc MUL_COUNTER,0 goto div_24x16_2 movf DIV_LO,W addwf REM_LO,F movf REM_HI,W div_24x16_2: movwf REM_HI bcf STATUS,C rrf MUL_COUNTER,F decfsz MUL_COUNTER,F goto div_24x16_1 rlf OUT_LO,F rlf OUT_MI,F rlf OUT_HI,F return [/asm]
Vielleicht hilft die Beschreibung der Microchip-Application note 544: http://ww1.microchip.com/downloads/en/AppNotes/00544d.pdf Math Utility Routines DOUBLE PRECISION DIVISION allerdings ist keine 24/16Bit-Division darunter, nur 16 oder 32 Bit
Div_24x16: clrwdt clrf REM_HI ;setze REM_HI =0 clrf REM_LO ;setze REM_HI =0 movlw .24 ;bewege dezimal 24 in arbeitsregister bit (3 u 4) =1 movwf MUL_COUNTER div_24x16_1: rlf OUT_LO,F ;schiebe die bits in OUT_LO um einen nach links, wo rlf OUT_MI,F ;bei das werthöchste bit in Status c steht. rlf OUT_HI,F ;nullen werden am wertniedrigsten bit nachgezogen. rlf REM_LO,F ;entspricht einer multiplikation mit 2 rlf REM_HI,F ;das werthöchste bit wird immer im nächsten ;register als wertniedrigstes wieder nachgezogen. rlf MUL_COUNTER,F ;save carry in counter (der übertrag des schiftens ;von REM_Hi wird in Mulcounter als wertniedrigstes ;bit gespeichert und gleichzeitig der momentane ;inhalt von mul counter um einen nach links ;geschiftet movf DIV_LO,W ;bewege div_lo nach w subwf REM_LO,F ;ziehe w von rem_lo ab und speichere es in rem_lo movf DIV_HI,W ;bewege div_hi nach w btfss STATUS,C ;[a]gab es bei der subtráktion eine ;unterschreitugn von null? ;von 0? incfsz DIV_HI,W ;[a]nein: erhöhe div_hi um einen und:[b]ist ;div_hi ==0? subwf REM_HI,W ;[a]ja und nein [b]nein:ziehe w von rem_hi ab btfsc STATUS,C ;[b]ja :[c]gab es bei der subtraktion eine ;nterschreitung von null? bsf MUL_COUNTER,0 ;[c]ja: setze das wertniedrigste bit in mulcounter btfsc MUL_COUNTER,0 ;[c]ja und nein:[d]ist das bit 0 in mul counter ;gesetzt!? goto div_24x16_2 ;[d]ja: gehe zu routine div_24x16_2(achtung inghalt ;in w wird beibehalten!) movf DIV_LO,W ;[d]nur nein, da ja ein goto ist:bewege div_lo nach ;w addwf REM_LO,F ;addiere w zu rem_lo und speichere es in rem_lo movf REM_HI,W ;bewege rem_hi nach w div_24x16_2: movwf REM_HI ;bewege w nach rem_hi bcf STATUS,C ;clear carry flag rrf MUL_COUNTER,F ;schiebe counter um ein bit nach rechts, speichere ;es wieder in mulcounter(entspricht einer teilung # ;durch 2)achtung: das wertniedrigste bit steht jetzt ;im carry flag decfsz MUL_COUNTER,F;veringere mul counter um 1,[e]ist mulcounter ==0 goto div_24x16_1 ;[e]nein: gehe zu routine div_24x16_1 rlf OUT_LO,F ;[e]ja:schiebe out_lo um einen nach links, ;spreichere über lauf bit in c rlf OUT_MI,F ;ziehe überlauf bit als niedrigstes mit ein, ;schiebe out_mí links,spreichere über lauf bit in c rlf OUT_HI,F ;ziehe überlauf bit als niedrigstes mit ein, ;schiebe out_hi links,spreichere über lauf bit in c
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.