Forum: Mikrocontroller und Digitale Elektronik Division in Assembler


von Mike R. (thesealion)


Lesenswert?

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]

von Christoph Kessler (db1uq) (Gast)


Lesenswert?

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

von Dennis (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.