![]() ![]() INFO - FAQ - CC2-Forum - CCPro-Forum |
|
Hallo OMICRO u. OMACRO Anwender, im Rahmen eines Projektes habe ich mich auch mit Arithmetik geschrieben in Inline Assembler fuer die OMACRO und OMICRO beschäftigt. Daraus ist das unten aufgefuehrte 32 Bit Programm fuer die OMACRO entstanden. Aehnlich aufgebaute Programme habe ich auch fuer 24 Bit fuer die OMACRO und fuer die OMICRO in 16, 24 und 32 Bit geschrieben. Das ganze Paket habe ich schon an Dietmar Harlos geschickt. Hier also nur die 32 Bit Auslegung fuer die OMACRO. Die dabei verwendete Wurzelfunktion ist rel. langsam, da bei der Wurzel von 2^32 insgesamt 65535 Durchläufe erfoderlich sind. Ein schnelleres Programm fuer die Wurzelfunktion zeige ich im naechsten Beitrag. Viel Spass an den OMICROs und OMACROS wuenscht Joe F ############### JF32ARIT.BAS ################################# ' JF32ARIT.BAS vom Mo. 23.03.2015 Josef Fenk; ' ' Umfang: 1640 Basic Bytes; 0 Sys-Bytes; 17 RAM-Bytes ' 32 Bit Arithmetik ' mit Subroutinen fuer ' 32 Bit Addition bzw. Subtraktion, ' schnelle 16bit x 16 Bit Multiplikation mit Ergebnis in 32 Bit ' einfache Division geradzahlig 2,4,8,etc. ' schnelle Division 32 Bit durch 8 Bit (1...255) mit Ergebnis 32 Bit ' Division 32Bit durch 32 Bit mit Ergebnis 32 Bit ' 32 Bit Square root = Wurzel ziehen mit Ergebnis in 16 Bit gerundet ' jedoch ist die Wurzelfunktion bei 2^32 etwas langsam, da 65535 Durchlauefe erforderlich sind ' Printausgabe der Zahlen als ganzzahlige Integerwerte ohne Vorzeichen ' Zahlenwertebereich der 32 bit Arithmetik ohne Vorzeichen ' Dezimal 255 255 255 255 ' 32-Bit-Zahl $00ff $00ff 00ff 00ff dezimal ausgeben: 0 bis 4.294.967.295 ' einige Teile des Programms basieren auf der ' Version 32BITASM.BAS von Dietmar Harlos ADPC vom 29. Juni 2006; ' --------------------------------------------------------------------------- ' --- Betriebssystem konfigurieren ------------------------------------------ INCLUDE "OMAC.DEF" 'Include-Datei mit Definitionen vom April 2010 ' --------------------------------------------------------------------------- ' --- Definitionen Variable fuer das Hauptprogramm DEFINE Ar_a AS LONG 'Erster 32-Bit-Akkumulator (1. Operand & Rechenergebnis) DEFINE Ar_b AS LONG 'Zweiter 32-Bit-Akkumulator (2. Operand) DEFINE Ar_c AS LONG 'Dritter 32-Bit-Akkumulator (temp. fuer DIV und PRINT32) DEFINE Ar_aw1 AS WORD[1] OF Ar_a ' low word doppelbyte 1-ter Eingabewert DEFINE Ar_aw2 AS WORD[2] OF Ar_a ' high word DEFINE Ar_a1 AS BYTE[1] OF Ar_a 'L_Byte DEFINE Ar_a2 AS BYTE[2] OF Ar_a 'Mid_L_Byte DEFINE Ar_a3 AS BYTE[3] OF Ar_a 'Mid_H_Byte DEFINE Ar_a4 AS BYTE[4] OF Ar_a 'Higest Byte DEFINE Ar_bw AS WORD[1] OF Ar_b ' 2-ter eingabe wert und benutzt bei Berechnun DEFINE Ar_b1 AS BYTE[1] OF Ar_b 'L_Byte DEFINE Ar_b2 AS BYTE[2] OF Ar_b 'Mid_L_Byte DEFINE Ar_b3 AS BYTE[3] OF Ar_b 'Mid_H_Byte DEFINE Ar_b4 AS BYTE[4] OF Ar_b 'Highest Byte DEFINE Ar_cw AS WORD[1] OF Ar_c ' Ausgabe Rest in div Proc DEFINE Ar_c1 AS BYTE[1] OF Ar_c 'L_Byte benutzt bei div. Berechnung und Ausgabe DEFINE Ar_c2 AS BYTE[2] OF Ar_c 'H_Byte bzw. Middle Byte von 32Bit wie oben DEFINE Ar_c3 AS BYTE[3] OF Ar_c 'Mid_H_Byte DEFINE Ar_c4 AS BYTE[4] OF Ar_c 'Highest Byte DEFINE tem1 BYTE ' benutzt bei Ausgabe DEFINE tem2 BYTE DEFINE tem3 BYTE DEFINE tem4 BYTE DEFINE i_z BYTE ' Zaehlbyte '***** Definition der Digitalen Ein- / Ausgabeports 'DEFINE Tast_P4 PORT[04] 'Warte-Taste ' Hauptprogramm----------------------------------------------- ' --------------------------------------------------------------------------- #Start Ar_a3=255:Ar_a2=255:Ar_a1=255 PRINT "Start Eingabe_Ar_a4=";Ar_a4 GOSUB anzeigen PRINT "davon Wurzel" GOSUB sqrt_32 Ar_a4=Ar_b4:Ar_a3=Ar_b3:Ar_a2=Ar_b2:Ar_a1=Ar_b1 GOSUB anzeigen PAUSE 100 PRINT "Eingabe_a 0...65535" INPUT Ar_aw1 'Eingabe 16 Bitzahl Ar_bw=Ar_aw1 PRINT "Eingabe_Ar_aw=";Ar_aw1,"Ar_b=";Ar_bw GOSUB anzeigen GOSUB addieren PRINT "Ergebnis_Addition" GOSUB anzeigen GOSUB subtrahieren PRINT "Ergebnis_Subtraktion" GOSUB anzeigen Ar_a4=0:Ar_b4=0:Ar_a3=0:Ar_b3=0 PRINT "Eingabe_Mult_a,b 0...65535" INPUT Ar_aw1 'Eingabe 16 Bitzahl Ar_bw=Ar_aw1 ' fuer quadratberechnung gleicher wert zugewiesen PRINT "Eingabe_Ar_aw1=";Ar_aw1,"Ar_bw=";Ar_bw GOSUB multi_16x16 Ar_a4=Ar_c4:Ar_a3=Ar_c3:Ar_a2=Ar_c2:Ar_a1=Ar_c1 ' zuweisung der ergebnisse PRINT "Ausgabe_Mul_a*a=quadrat" GOSUB anzeigen GOSUB divid_8 PRINT "Ausgabe_Div_8" GOSUB anzeigen Ar_a4=255:Ar_a3=255:Ar_a2=255:Ar_a1=255 PRINT "Eingabe_Divisor 0...255" INPUT Ar_b1 PRINT "Eingabe_Ar_b1=";Ar_b1 GOSUB anzeigen PRINT "nun ./. Ar_b1" GOSUB div_8b Ar_a4=Ar_c4:Ar_a3=Ar_c3:Ar_a2=Ar_c2:Ar_a1=Ar_c1 PRINT "Ostemp=";ostemp,"Rem_H_vor=";tem3,"Rem_H_nach=";tem2 GOSUB anzeigen PAUSE 100 Ar_a4=0:Ar_b4=0:Ar_a3=0:Ar_b3=0 PRINT "Eingabe_Mult_a,b 0...65535" INPUT Ar_aw1 'Eingabe 16 Bitzahl Ar_bw=Ar_aw1 ' fuer quadratberechnung gleicher wert zugewiesen PRINT "Eingabe_Ar_aw1=";Ar_aw1,"Ar_b=";Ar_bw GOSUB multi_16x16 Ar_a4=Ar_c4:Ar_a3=Ar_c3:Ar_a2=Ar_c2:Ar_a1=Ar_c1 ' zuweisung der ergebnisse PRINT "Ausgabe_Mul_a*a=quadrat" GOSUB anzeigen GOSUB sqrt_32 'Ergebnis in Ar_b PRINT "Ausgabe_Wurzel" Ar_a4=Ar_c4:Ar_a3=Ar_c3:Ar_a2=Ar_c2:Ar_a1=Ar_c1 ' zuweisung der ergebnisse GOSUB anzeigen #Div_Test 'ab hier divisionstest Ar_a4=0:Ar_b4=0:Ar_c4=0:Ar_a3=0:Ar_b3=0:Ar_c3=0:tem3=0:tem2=0:tem1=0 PRINT "Eingabe_Mult_a,b nur 1xmal 0...65535" INPUT Ar_aw1 'Eingabe 16 Bitzahl Ar_bw=Ar_aw1 ' fuer quadratberechnung gleicher wert zugewiesen PRINT "Eingabe_Ar_aw1=";Ar_aw1,"Ar_bw=";Ar_bw GOSUB multi_16x16 Ar_a4=Ar_c4:Ar_a3=Ar_c3:Ar_a2=Ar_c2:Ar_a1=Ar_c1 ' zuweisung der ergebnisse PRINT "Ausgabe_Mul_a*a=quadrat" GOSUB anzeigen PRINT "Eingabe_divisor_Ar_b: 0...65535" Input Ar_bw GOSUB div_32_16 PRINT "Ausgabe_Division" GOSUB anzeigen GOTO Start End2Host=ON END ' ****** Subroutinen --------------------------------------------------------------------------- ' Akkumulatoren ausgeben PROC anzeigen PrintHex=ON PRINT "Akku_a: $";Ar_a4;Ar_a3;Ar_a2;Ar_a1;" dezimal ausgeben: "; print32 tem4=Ar_a4:tem3=Ar_a3:tem2=Ar_a2:tem1=Ar_a1 ' Zwischenspeichern, damit Werte erhalten bleiben Ar_a4=Ar_b4:Ar_a3=Ar_b3:Ar_a2=Ar_b2:Ar_a1=Ar_b1 PRINT "Akku_b: $";Ar_b4;Ar_b3;Ar_b2;Ar_b1;" dezimal ausgeben: "; print32 Ar_a4=Ar_c4:Ar_a3=Ar_c3:Ar_a2=Ar_c2:Ar_a1=Ar_c1 PRINT "Akku_c: $";Ar_c4;Ar_c3;Ar_c2;Ar_c1;" dezimal ausgeben: "; print32 Ar_a4=tem4:Ar_a3=tem3:Ar_a2=tem2:Ar_a1=tem1 PrintHex=OFF RETURN ' ******************************************************************* ' ab hier 32Bit Arithmetik ' Subroutinen Addition, Subtraktion,Multiplikation, ' einfache Division geradzahlig 2,4,8,etc.und beliebige Division gerundet ' sowie Square root = Wurzel ziehen ' sowie ausgabe der Ergabniszahl als integer wert ohne vorzeichen '******************************************************************** ' Subroutine zur 32-Bit-Addition ' Eingabewerte_1 muess in Ar_a4 bis Ar_a1 sein ' Eingabewerte_2 muess in Ar_b4 bis Ar_b1 sein ' Ausgabewerte sind in Ar_a4 bis Ar_a1 PROC addieren INLASM ! lda Ar_a+3 ' lowest byte in accu ! add Ar_b+3 ! sta Ar_a+3 ! lda Ar_a+2 ! adc Ar_b+2 ! sta Ar_a+2 ! lda Ar_a+1 ' Mid_hi byte in accu ! adc Ar_b+1 ! sta Ar_a+1 ! lda Ar_a ' highest byte in accu ! adc Ar_b ! sta Ar_a ! rts END PROC ' Subroutine zur 32-Bit-Subtraktion ' Eingabewerte_1 muess in Ar_a4 bis Ar_a1 sein ' Eingabewerte_2 muess in Ar_b4 bis Ar_b1 sein ' Ausgabewerte sind in Ar_a4 bis Ar_a1 PROC subtrahieren INLASM ! lda Ar_a+3 ! sub Ar_b+3 ! sta Ar_a+3 ! lda Ar_a+2 ! sbc Ar_b+2 ! sta Ar_a+2 ! lda Ar_a+1 ! sbc Ar_b+1 ! sta Ar_a+1 ! lda Ar_a ' highest byte in accu ! sbc Ar_b ! sta Ar_a ! rts END PROC ' --------------------------------------------------------------------------- ' Schnelle Multiplikation 16Bit Wordvariable mit 16Bit Word Variable ' mit 32-Bit-Ergebnis ' von Josef Fenk Mo. 22.03.2015 ' Eingabewerte_1=Multiplikand muess in Ar_a2 bis Ar_a1 sein ' Eingabewerte_2=Multiplikator muess in Ar_b2 bis Ar_b1 sein ' Ausgabewerte=Produkt sind in Ar_c4 bis Ar_c1 ' Verfahren der Multiplikation s. auch ATMEL application note AVR201 ' Prod Eingabe_A Eingabe_B Ergebnisse ' A_H:A_L x B_H:B_L C_H C_ML C_ML C_L '---------------------------------------------------------------------- ' 1-te Mul. A_L x B_L ==> P1_H P1_L ' 2-te Mul. A_H x B_L ==> +c P2_H P2_L ' 3-te Mul. A_L x B_H ==> +c P3_H P3_L ' 4-te Mul. A_H x B_H ==> P4_H P4_L '------------------------------------------------------------------------- ' Summation der 4 Multiplikationen C_M:C_MH:C_ML:C_L ' uebertragen in Ar_c4:Ar_c3:Ar_c2:Ar_c1 ' C_H bzw. P4_H wird beruecksichtigt, um 32 Bit Ergebnis auszugeben PROC multi_16x16 INLASM ' 1-te Multiplikation ! lda Ar_a+3 ' Eingabe a1 low byte in accu ! ldx Ar_b+3 ' Eingabe b1 low byte in x register ! mul ' Mul_1 P1_H byte in x; P1_L in accu ! sta Ar_c+3 ' accu=P1_L low byte in Ausgabe Ar_c1 ! stx Ar_c+2 ' P1_H high byte in Ar_c2 ' 2-te Multiplikation ! lda Ar_a+2 ' Eingabe a1 high byte in accu ! ldx Ar_b+3 ' Eingabe b1 low byte in x ! mul ' Mul_2 P2_H high byte in x-register; P2_L low byte in accu ! stx Ar_c+1 ' P2_H high byte in Ausgabe Ar_c3 mid_high byte abspeichern ! add Ar_c+2 ' P1_H zwischengespeichert in Ar_c2 zu P2_L low byte in accu addieren ! sta Ar_c+2 ' Ergebnis abgespeichert ! lda Ar_c+1 ' ! adc #0 ' Ar_c3+ c ev. carry von add Ar_c+2 uebertragen ! sta Ar_c+1 ! lda Ar_c ' falls carry von vorher ! adc #0 ' nun carry uebertagen ! sta Ar_c ' accu zurueck in c ' 3-te Multiplikation ! lda Ar_a+3 ' Eingabe a1 low byte in accu ! ldx Ar_b+2 ' Eingabe b2 high byte in x register ! mul ' Mul_3 P3_L low byte in accu; P3_H high byte in x ! add Ar_c+2 ' P3_L + (P2_L+P1_H) addition ! sta Ar_c+2 ' additionsergebnis accu in Ausgabe mittel byte speichern ! txa ' P3_H in accu ! adc Ar_c+1 ' Ar_c3 + carry von voher addieren ! sta Ar_c+1 ! lda Ar_c ! adc #0 ! sta Ar_c 'alle uebertrage in c ' 4-te Multiplikation ! lda Ar_a+2 ' Eingabe high byte in accu ! ldx Ar_b+2 ' Eingabe b1 high byte in x ! mul ' Mul4 P4_L low byte in accu; P4_H high byte in x-register, wird genutzt ! add Ar_c+1 ' P2_H in Ar_c3 zwischengespeichert nun zu P4_L in accu addieren ' P2_H+P4H mit ev. carry von vorherigen Additionen in Ar_c ! sta Ar_c+1 ' accu ergebnis in Ar_c3 ! lda Ar_c ! adc #0 ! sta Ar_c ! txa ' transfer x-register = P4_H in accu ! add Ar_c 'Ar_c zu accu addieren ! sta Ar_c ' accu nach Ar_c4 highest byte kopieren ! rts END PROC ' Subroutine fuer 32 bit Zahl; Division durch 8 mit Rundung ' Eingabewerte_1 muess in Ar_a4 bis Ar_a1 sein ' Ausgabewerte sind in Ar_a4 bis Ar_a1 PROC divid_8 INLASM ! lda Ar_a+3 ' Nun halben divisor zu dividend addiert zwecks Rundung ! add #4 ' halben Teilerwert addieren ! sta Ar_a+3 ! lda Ar_a+2 ! adc #0 ' falls carry dann uebertrag von carry ! sta Ar_a+2 ! lda Ar_a+1 ! adc #0 ' falls carry dann uebertrag von carry ! sta Ar_a+1 ! lda Ar_a ! adc #0 ! sta Ar_a 'Ende vorbereitung fuer Rundung des Ergebnisses ! lda #3 ' division :/.2 dazu fuer./.4==#2; ./.8==#3; ./.16==#4 etc. einfuegen #Div_schl ' divisionsschleife ! lsr Ar_a ' MSB verschoben um eins nach rechts; Bit0= in carry ! ror Ar_a+1 ' carry in Bit 7 von Ar_a+1 =uebertragen in drittes byte ! ror Ar_a+2 ' carry in Bit 7 von Ar_a+2 =in = zweites byte ! ror Ar_a+3 ' carry in Ar_a1 uebertragen ! dbnza Div_schl 'wiederholt div_schl bis accu = 0 ist ! rts END PROC ' ******************************************************************* ' ab hier 32Bit Arithmetik Division durch 8 Bit mit Div Befehl u. Rundung '******************************************************************** ' Subroutine zur 32-Bit-Division; 4 Byte-Wert / 1 Byte-wert=Ergebnis in 4 Byte ' geaendert Sa. 14.03.2015 von JF, um integerzahlen ohne neg. Werte zu erhalten ' Wertebereich fuer Ausgabe begrenzt ' auf 2^32 = 4.294.967.295==Hex: ff ff ff ff ' Urversion von Dietmar Harlos ADPC am 29. Juni 2006 in 32BITASM.BAS PROC div_8b INLASM ! mov Ar_a+3,Ar_c+3 'Akkumulator a nicht veraendern ! mov Ar_a+2,Ar_c+2 ! mov Ar_a+1,Ar_c+1 ! mov Ar_a,Ar_c ! ldx Ar_b1 '#100 ' divisior = 10 in x register laden ! clr OSTEMP #print10_2 ! inc OSTEMP ' zaehlt hoch ! clrh ' high byte of dividend =0 gesetzt ! lda Ar_c ' lade dividend highest byte in accu ! div ' Division durch 10;quotient in accu; remainder in H ! sta Ar_c ! lda Ar_c+1 ! div ! sta Ar_c+1 ! lda Ar_c+2 ! div ! sta Ar_c+2 ! lda Ar_c+3 ! div ' ergebnis in accu und remainder in H ! sta Ar_c+3 ! pshh ' remainder in stack ! pula ' nun in accu ! sta tem3 ' nun h-register in tem3 ! txa ' x-registor= divisor in accu ! lsra ' accu inhalt um 1 nach rechts, divisor halbiert ! add tem3 ' divisor/2 + tem3== divisor/2 + remainder ! clrh ' H register loeschen ! div ' quotient in accu, remainder in H ! add Ar_c+3 ' ! sta Ar_c+3 ' ergebnis accu zurueck in Ar_c+3 ! pshh ' remainder in stack ! pula ' nun in accu ! sta tem2 ' h-register nach rundung in tem2 ! rts END PROC ' 32-Bit-Division mit 32-Bit Ergebnis integerzahlen ohne Vorzeichen ' Eingabewert Dividend muss in Ar_a1 bis Ar_a4 sein==Hex: = 0... ' Eingabewert Divisor muss in Ar_b1 bis Ar_b4 sein= 0... ' Ausgabewert Quotient in Ar_a1 bis Ar_a4 = 0... ' geaendert Di. 17.03.1015 von JF, ' Urversion von Dietmar Harlos ADPC am 29. Juni 2006 aus 32BITASM.BAS PROC div_32_16 INLASM ! clr Ar_c ! clr Ar_c+1 'Akkumulator c loeschen ! clr Ar_c+2 ! clr Ar_c+3 ! mov #32,OSTEMP ' schleifenzaehler zuweisen der variablen ostemp (ist in OM_FW.PRO) #div32_1 ! lsl Ar_a+3 'Dividend (= Quotient, Ergebnis) a nach links ... ! rol Ar_a+2 ! rol Ar_a+1 ! rol Ar_a ! rol Ar_c+3 'in den Akkumulator c schieben ! rol Ar_c+2 ! rol Ar_c+1 ! rol Ar_c ! lda Ar_c+3 'Akkumulator c minus Divisor b ! sub Ar_b+3 ! lda Ar_c+2 ! sbc Ar_b+2 ! lda Ar_c+1 ! sbc Ar_b+1 ! tax 'Zwischenspeichern ergebnis accu Ar_c2 in x register ! lda Ar_c ! sbc Ar_b ! bcs div16_2 'carry ist gesetzt, wenn Akkumulator kleiner als Divisor ! sta Ar_c 'accu in Ar_c3 ! stx Ar_c+1 'voriges ergebnis von accu, zwischengespeichert in x nun zurueck in Ar_c2 ! lda Ar_c+3 'Ar_c1 in accu ! sub Ar_b+3 'Ar_b1 subtrahieren ! sta Ar_c+3 'ergebnis in accu zurueck in Ar_c1 ! lda Ar_c+2 ! sbc Ar_b+2 ! sta Ar_c+2 ! inc Ar_a+3 ' und LSB vom Quotienten setzen #div16_2 ! dbnz OSTEMP,div32_1 ! rts END PROC ' Procedure Wurzel aus 32 Bit Zahl ' Eingabewert=Radikand muss in Ar_a1 bis Ar_a4 sein ' Ausgabewert=Wurzelwert in Ar_b1 bis Ar_b2 ' Quadratwurzel von einer 32-Bit-Zahl, mathematisch korrekt gerundet! ' Wertebereich fuer Wurzeleingabe begrenzt auf ' bei 0...4.278.190.079==H: fe ff ff ff ==> Ausgabe 0...65408 ' bei 4.294.967.295==H: ff ff ff ff ==> Ausgabe 256 ' erweitert von JFenk auf 32 Bit; Mo. 23.03.2015 ' nach DHarlos-SQR-Funktion aus dem Open-Micro-Betriebssystem fuer 8Bit Zahl ' Ur-Algorithmus stammt von Rene Stadler alias Topmail ' angewendetes Verfahren, von Zahl a soll die Quadratwurzel gebildet werden ' 1. SQRT (a) = (a-1)/2; dies ist die Einstiegsberechnung;wobei b das Ergebnis durch schleifennaeherung ermittelt wird ' 2. SQRT (a) = (Ergebnis aus 1.) - b; b=1 beim erstenmal; ' 3. SQRT (a) = (Ergebnis aus 2.) - b; b=b+1 usw. ' hier als Beispiel z.B. a=15 ' 1-te Iteration SQRT(a) = ((15-1)/2) -1 = (14/2) -1 = 7-1 = 6 ' 2-te " SQRT(a) = 6 - 2 = 4 ' ' 3-te " SQRT(a) = 4 - 3 = 1 ' 4-te " SQRT(a) = 1 - 4 = -3 ; hier endet die Berechnung, da das Ergebnis negativ ist ' b=4 ist mathematisch korrekt gerundet; die Anzahl der Schleifendurchlaeufe = dem Ergebnis b ' es ist fuer grosse Zahlen nicht das schnellste Verfahren, ' da z.B. bei voller 32 Bit Zahl= 65408 schleifendurchlaeufe erfolgen ' in meiner Anwendung ist das Ergebnis jedoch meistens unter 1000 PROCEDURE sqrt_32 INLASM '!!! ! ldhx Ar_aw1 ' kopiert Ar_aw1 high byte=2 in H u. low Byte1 in X; index reg. H:X u setzt Flag Z, wenn wert=0 ist ! bne Test1_0 'wenn Ar_a nicht 0 ist , wird Z Flag nicht gesetzt und Sprung erfolgt ! lda #0 ' accu auf 0 gesetzt, damit Z Flag wieder zurueckgesetzt werden kann ! tap ' accu kopiert in CCR register, damit Z bit auf 0 setzen ! lda Ar_aw2 ' kopiert Ar_aw2 high byte inH u. low byte in X; setzt Z-Flag, wenn wert Ar_a3=0 ist ' nur wenn beide Ar_aw1 und Ar_aw2=0 sind, dann soll sprung nach sqrint_2 erfolgen ! beq sqrint_2 'wenn Ar_aw1= 0 und Ar_aw2=0 branch if equal bzw. Z-bit equal=0 #Test1_0 ' ! clrx ' loescht x register ! clrh ' loescht h-register ! lda Ar_a+3 ' erstes Byte in accu ! sub #1 ' subtrahiert von Ar_a1=accu-1; ja nicht #-1 eingeben ! sta Ar_a+3 ' neuen accuwert zurueck kopieren ! lda Ar_a+2 ' ! sbc #0 ' falls carry vorher gesetzt wurde uebrtragen in accu ! sta Ar_a+2 ' neuen accuwert zurueck kopieren in a2 ! lda Ar_a+1 ' ! sbc #0 ' falls carry vorher gesetzt wurde uebrtragen in accu ! sta Ar_a+1 ' neuen accuwert zurueck kopieren in a2 ! lda Ar_a ' ! sbc #0 ' falls carry vorher gesetzt wurde, uebertragen in accu ! sta Ar_a ' ! lsr Ar_a ' logic shift right MSB-byte von 3byte Zahl und Bit0 in carry ! ror Ar_a+1 ! ror Ar_a+2 ' roll right low word byte bzw. middle byte von 3byte wort, dabei carry von Ar_a3 in Ar_a2 bit 7 Âbertragen ! ror Ar_a+3 ' roll right low byte von 3byte wort, dabei carry von Ar_a2 in Ar_a1 bit 7 Âbertragen u. wert halbiert ' (eingabewert -1)/2 berechnet ! clr Ar_b+3 ' loescht Ergebnisbyte Ar_b1 ! clr Ar_b+2 ' loescht Ergebnis Byte 2 #sqrint_1 ' Schleife ! lda Ar_b+3 ' Ar_b1 in accu ! add #1 ' accu + 1 zaehlt den Wurzelergebiswert hoch durch naeherung ! sta Ar_b+3 ' accu in Ar_a1 ! lda Ar_b+2 ' Ar_b2 in accu ! adc #0 ' accu+carry von vorher ! sta Ar_b+2 ' accu in Ar_a2 zurÂck ' nun SQRT-Naeherung berechnen ! lda Ar_a+3 ' Eingabe Ar_a1 in accu ! sub Ar_b+3 ' accu - Ar_b1 ! sta Ar_a+3 ' accu in Ar_a1 ! lda Ar_a+2 ' Ar_a2 in accu ! sbc Ar_b+2 ' accu- Ar_b2-carry von vorher ! sta Ar_a+2 ' accu in Ar_a2 zurueck ! lda Ar_a+1 ' Ar_a3 in accu ! sbc #0 ! sta Ar_a+1 ! lda Ar_a ' Ar_a in accu ! sbc #0 ' accu - #0 - carry von vorheriger subtraction ! sta Ar_a ' accu in Ar_a4 zurueck ! bcc sqrint_1 ' branch if carry bit clear; sobald carry bit gesetzt ist wird beendet #sqrint_2 ! rts ' Ergebnis wird ausgegeben in Ar_b END PROCEDURE ' Subroutine zur dezimalen Ausgabe von 32-Bit-Zahlen= dez 10 stellig ohne Vorzeichen ' geaendert Sa. 14.03.2015 von JF, um integerzahlen ohne neg. Werte zu erhalten ' Wertebereich fuer Ausgabe begrenzt ' auf 2^32 = 4.294.967.295==Hex: ff ff ff ff ' Urversion von Dietmar Harlos ADPC am 29. Juni 2006 in 32BITASM.BAS PROC print32 INLASM ! mov Ar_a+3,Ar_c+3 'Akkumulator a nicht veraendern ! mov Ar_a+2,Ar_c+2 ! mov Ar_a+1,Ar_c+1 ! mov Ar_a,Ar_c ! ldx #10 ' divisior = 10 in x register laden ! clr OSTEMP #print32_2 ! inc OSTEMP ' zaehlt hoch ! clrh ' high byte of dividend =0 gesetzt ! lda Ar_c ' lade dividend low byte in accu ! div ' Division durch 10;quotient in accu; remainder in H ! sta Ar_c ! lda Ar_c+1 ! div ! sta Ar_c+1 ! lda Ar_c+2 ! div ! sta Ar_c+2 ! lda Ar_c+3 ! div ! sta Ar_c+3 ! pushh 'pushh = pshh remainder in H auf stack speicher ! ora Ar_c+2 ' vergleich accu mit ar_c+2 ! ora Ar_c+1 ! ora Ar_c ! bne print32_2 'branch if not equal; test Z bit of CCR and branch if Z=0 #print32_3 ! popa 'Ziffern holen von stack und ausgeben; popa=0pula ! add #"0" ! jsr FwPutSci ! cli ' clears interrupt bit I = bit 3 of CCR ! dbnz OSTEMP,print32_3 'decrement and branch if not zero; wenn OSTEMP>0 sprung zu print32_3 ! rts END PROC ' --------------------------------------------------------------------------- INCLUDE "OM_FW.PRO" |
Antwort schreiben |