📄 div.asm
字号:
move.l 0(a1),d1 * d1 = neue Laenge Divisor, a1->* * 1. Zi Divisor move.l 0(a1,d1.l*4),-(sp) * fuehrende und naechste Zi Di- move.l -4(a1,d1.l*4),-(sp) * visor auf Stack merken move.l 0(a1,d1.l*4),d5 * d5 = neue fuehrende Zi Divisor***startdiv: lea divident,a0 * a0->Laengenfeld div-Feld addq.l #4,a1 * a1->fuehrende Zi Divisor move.l (a0)+,d0 * d0=neue Laenge div-Feld sub.l d1,-4(a0) * Anzahl der Divisionsschritte addq.l #1,-4(a0) * = L(Dt)-L(dr), evtl. +1 move.l -4(a0),-(sp) * auf Stack merken move.l #4,d4 * fuer Pointer = Anzahl der mulu.l d0,d4 * Ziffern * 4 add.l d4,a0 * a0->fuehrende Zi div-Feld move.l #0,(a0)+ * vor fuehrende Zi div-Feld wird* * eine 0 eingetragen, a0->davor! move.l 0(sp),d0 * d0=Anzahl Divisionsschritte* * = L(Dt) - L(Dr), evtl. +1 lea quotient,a3 * a3->Laengenfeld quot-Feld move.l #4,d4 * d4 fuer Pointerausrichtung mulu.l d0,d4 add.l d4,a3 add.l #4,a3 * a3->vor fuehrende Zi quot-Feld subq.l #1,d0 * d0 Schleifenzaehler, Schlei-* * fenende bei -1mainloop: move.l -(a0),d7 * d7=fuehrende Zi div-Feld move.l a0,a2 * a2->fuehrende Zi div-Feld move.l d1,d2 * d2 = Laenge Quotient * 4 mulu.l #4,d2 * (wg. 4 Byte/Ziffer) sub.l d2,a2 * a2->niedrigste Zi div-Feld,* * die bei mult und subtr ange-* * sprochen wird cmp.l d7,d5 * hoechste Zi div-Feld = v1 ? bne dodivide * nein => q^ durch Division er-* * mitteln move.l #-1,d3 * ja => d3=q^=b-1=2**32-1=1...1 bra dotest * q^ testendodivide: move.l -4(a0),d6 * d6d7 = u1u0 divu.l d5,d7:d6 * u0u1 : v1, d6=Quotient,d7=Rest move.l d6,d3 * d3 = q^dotest: lea testfeld,a4 * a4->testfeld move.l 4(sp),d4 * d4d5 = v2v1 mulu.l d3,d2:d4 * d4d2 = q^*v2, d2 hoeherwertig move.l d4,0(a4) * niederwertiges Testergebnis move.l d2,4(a4) * ablegen, hoeherwertiges merken mulu.l d3,d2:d5 * d5d2 = q^*v1, d2 hoeherwertig add.l d5,4(a4) * auf 2. Testfeld addieren bcc nocarry1 * Uebertrag ? nein => weiter addq.l #1,d2 * ja => addiere 1 auf hoeherw.nocarry1: cmp.l 0(a0),d2 * vergleiche hoechstwertiges* * Testergebnis mit u0 bcs okay * u0 groesser: okay bhi docorrect * u0 kleiner: q^ korrigieren move.l 4(a4),d2 cmp.l -4(a0),d2 * gleich: weiter vergleichen bcs okay bhi docorrect move.l 0(a4),d2 cmp.l -8(a0),d2 * beim letzten Vergleich okay bls okay * bei -8(a0)>=d2 !** q^ ist um eins zu gross: korrigieren*docorrect:subq.l #1,d3** Jetzt ist q^ okay, die Division kann beginnen, d.h. q^ * v wird* von den entsprechenden u-Stellen abgezogen*okay: eor.l d5,d5 * Uebertragsregister loeschen move.l d1,d2 * d2 Schleifenzaehler, Schlei- subq.l #1,d2 * fenende bei -1loopsub: move.l (a1)+,d6 * d6=niederwertigste Zi Divisor mulu.l d3,d7:d6 * vn*q^=d6d7,d7 hoeherwert. Teil add.l d5,d6 * addiere Uebertrag bcc nocarry2 * Carry ? nein=> weiter addq.l #1,d7 * ja => add. 1 auf hoeherw. Teilnocarry2: sub.l d6,(a2)+ * subtrahieren von niederwert.* * Zi vom div-Feld bcc nocarry3 * Borrow ? nein => weiter addq.l #1,d7 * ja => beim naechsten Schritt* * eins mehr abziehennocarry3: move.l d7,d5 * Uebertrag merken dbra d2,loopsub * Quot.fertig? Nein => Schleife sub.l d5,0(a2) * ja => subtrahiere letztes* * Multiplikationsergebnis bcc noreadd * Borrow ? nein => weiter** q^ * v > u , daher muss 1*v wieder auf u aufaddiert und q^ um* eins vermindert werden* subq.l #1,d3 * q^ = q^ - 1 move.l #4,d4 * d4 wird wieder Offset mulu.l d1,d4 sub.l d4,a2 * a2->niedrigste Zi von u zum sub.l d4,a1 * Addieren, a1->niedr.Zi von v move.l d1,d2 * d2 Schleifenzaehler, Schlei- subq.l #1,d2 * fenende bei -1 and.b #$ce,ccr * CCR zuruecksetzenloopreadd:move.l (a1)+,d5 * d5 = aktuelle Zi Quotient move.l 0(a2),d6 * d6 = aktuelle Zi Div-Feld addx.l d5,d6 * addiere auf div-Feld mit Carry move.l d6,(a2)+ * Summe in div-Feld eintragen dbra d2,loopreadd * Quot. fertig? nein=>Schleife move.l #0,(a2)+ * jetzt ist die hoechstwertige* * Zi vom div-Feld = 0** Die Division ist beendet. a1->vor fuehrende Zi Divisor* a2->vor fuehrende Zi div-Feld*noreadd: move.l d3,-(a3) * Quotient eintragen, a3->* * naechstgroesste Ziffer move.l #4,d4 * fuer Pointer-Zuruecksetzung mulu.l d1,d4 sub.l d4,a1 * a1->1. Zi Divisor move.l 8(sp),d5 * d5=fuehrende Zi Divisor = v1 dbra d0,mainloop * Div. fertig? nein => Schleife** Laenge von Quotient und Rest (=div-Feld) bestimmen* move.l 0(sp),d0 * d0=Anzahl Div.Schritte cmp.l #0,-4(a3,d0.l*4) * fuehrende Quot.Ziffer = 0 ? bne nocorr2 * nein => L(Quot)=L(Div)-L(Divi-* * sor) = Anzahl Div.Schritte subq.l #1,d0 * ja => L(Quot) eins groessernocorr2: move.l d0,-4(a3) * Laenge Quotient eintragen lea divident,a2 * a2->Laengenfeld Rest * Die Laenge vom Rest kann hoechst gleich der Laenge vom Divisor* sein.*loopchklngth: cmp.l #0,0(a2,d1.l*4) * Ist diese = 0? bne found * nein => Laenge klar subq.l #1,d1 * nein => L. mind. 1 kuerzer bra loopchklngth * weiter suchenfound: move.l d1,0(a2) * Laenge Rest eintragen** Erweiterung vom Rest (frueher div-Feld) und Quotient rueckgaengig* machen* move.l 12(sp),d4 * d4 = Erweiterungsfaktor cmp.l #0,d4 * wurde ueberhaupt erweitert ? beq noreshift * nein => weiter neg.l d4 * andersrum shiften subq.l #4,a1 * a1->L-Feld Divisor* * a2->L-Feld Rest move.l a1,-(sp) * Adresse Divisor und Shift- move.l d4,-(sp) * faktor auf Stack schreiben move.l a1,-(sp) move.l a$shift,a0 jsr (a0) * Programm aufrufen move.l a2,0(sp) * dasselbe fuer Rest move.l a2,8(sp) move.l a$shift,a0 jsr (a0) * Programm aufrufen add.l #12,sp * Stackpointer zurueckschaltennoreshift:add.l #16,sp * Shiftfaktor etc. wird nicht* * mehr gebraucht** Ergebnisse uebertragen: Quotient kommt zuerst dran und wird dabei* evtl. ueberschrieben* subq.l #4,a3 * a3->L-Feld Quotient move.l 0(a3),d2 * d2 Schleifenzaehler, Schlei- move.l 68(sp),a4 * a4->L-Feld Quotientloopquot: move.l (a3)+,(a4)+ * uebertragen dbra d2,loopquot * fertig ? nein => Schleife move.l 0(a2),d2 * d2 wieder Schleifenzaehler move.l 72(sp),a4 * a4->L-Feld Restlooprest: move.l (a2)+,(a4)+ * uebertragen dbra d2,looprest * fertig ? nein => Schleife eor.l d0,d0 * alles fertig, RC = 0 return: movem.l (sp)+,a0/a1/a2/a3/a4/a5/a6/d1/d2/d3/d4/d5/d6/d7 rtsnull: dc.l 0,0,0,0,0,0,0,0,0,0,0,0,0 * 13 Langworte 0 zum Loeschen END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -