;************************************** ;* Quadratwurzel mit * ;* dem Newton Raphson Verfahren * ;* 2006 H.V.Viehof * ;************************************** ;______________________________________ ; ;stapelsegment : ;______________________________________ stack segment stack word 'stack' dw 100 dup (?) stack ends ;______________________________________ ; ;programmsegment : ;______________________________________ code segment public word 'prog' org 0 main: call init call there mov ax,04c00 ;dos eqivalent zu 'ExitProccess' int 021 init: mov ax,seg Buffer ;daten- und extrasegment initialisieren mov es,ax mov ds,ax ret ;______________________________________ ; ;ab hier muss der Code Stehen ;______________________________________ there: mov dx, offset intro mov ah, 9 int 021 mov word ptr[Save], 0 mov word ptr[Count], 0 call _input cmp al, 'q' jz ret call _newton mov di, offset Buffer call _output mov dx, offset Ausg mov ah, 9 int 021 mov ax, [Count] mov di, offset Buff02 call _output mov dx, offset Iter mov ah, 9 int 021 jmp there ret _newton: mov bx, 3 ; das Newton Raphson Verfahren mov cx, 0ffff ; Zähler für max. Iteration X1: xor dx, dx ; DX löschen da es bei der Division benutzt wird mov ax,[Save] ; den Wert in AX div bx ; und durch BX teilen cmp ax, bx ; Wenn AX == BX ist die gesuchte Wurzel gefunden jz _exit ; dann ist hier Schluss ;-) add bx, ax ; sonst Mittelwert bilden: (AX+BX) shr bx, 1 ; /2 inc word ptr[Count] ; der [Count] Zähler zeigt die Schleifen durchläufe loop X1 ; von vorn, sofern nicht max. Iteration überschritten _exit: ret ; hier fertig und zurück! _input: mov bl, 10 ; Multiplikationsfaktor GetIt: mov ah,1 ; Int 021 Funktion 1: Zeichen von der Tastatur lesen int 021 and ax, 0ff ; nur das in al wird benötigt cmp al, 0d ; ist es die Enter Taste? jz ret ; dann ist das hier fertig cmp al, 'q' ; Ist es die 'q' Taste jz ret ; Rücksprung und das Programm wird geschlossen cmp al, '9' ; Grösser als 9? jg GetIt ; Keine Ziffer, also nochmal cmp al, '0' ; kleiner 0? jl GetIt ; wohl auch keine Ziffer sub al, '0' ; vom ASCII die Null abziehen push ax ; das wird gesichert mov dx, 0 ; dx auf Null (dx nimmt an einer Multiplikation teil) mov ax,[Save] ; die Ausgabe in ax laden mul bx ; mal 10 bewirkt eine Dezimalstelle nach links schieben mov [Save], ax ; und wieder abspeichern pop ax ; so her mit der Ziffer! add [Save], ax ; Zu der Ausgabevariablen addieren jmp GetIt ; Und die nächste Ziffer holen _output: cld mov bx,10 mov cx,0 X1: xor dx ,dx ; dx löschen div bx ; dx:ax durch bx (10) teilen add dl, 030h ; dem divisionsrest 30h hinzuaddieren push dx ; auf den stapel legen inc cx ; durchlauf zähler erhöhen cmp ax, 0 ; ist ax schon 0? jnz X1 ; nicht? dann das ganze noch einmal... rücksprung nach X1 X2: ; Ok, die Zahl wird einmal rumgedreht pop dx ; dx vom stapel mov [di],dl ; und dl in den an position [di] Puffer schreiben inc di ; schreibzeiger erhöhen loop X2 ; bis Durchlaufzähler = 0 mov al,10 stosb mov al,13 stosb mov al, '$' stosb ret code ends ;______________________________________ ; ;datensegment : ;______________________________________ data segment public word 'daten' Ausg db 0a, 0d db "Ausgabe (Wurzel):" Buffer db 16 dup (0) Iter db "nach Iterationen:" Buff02 db 16 dup (0) Save dw ? Count dw ? Intro db 0a,0d db "**********************************************************",0a,0d db "* Quadratwurzel mittels des Newton_Raphson-Verfahrens. *",0a,0d db "* Berechnet die ganzzahlige Wurzel der Eingegebenen Zahl *",0a,0d db "* Programm Beenden mit *",0a,0d db "* 2006 Heinz Volker Viehof *",0a,0d db "**********************************************************",0a,0d db 0a,0d,0a,0d db "Eingabe:$" data ends end