home *** CD-ROM | disk | FTP | other *** search
- ; ----------------------------
- ; LONGINT.DEM - Demo für die Routinen in LONGINT.LIB
- ;
- ; (c) Bernd Schemmer 1990 - 1992
- ; Letzter Update: 15.02.1992
- ;
- ; Übersetzen:
- ; A86 LONGINT.DEM DEMOS.INC TO LONGINT.COM
- ;
- ; Hinweis: Die Environment-Variable 'A86' muß den Dateinamen 'MACROS.MAC'
- ; enthalten und die .LIB-Dateien müssen über die Datei A86.LIB
- ; erreichbar sein.
- ;
- ; ----------------------------
-
- jmp start
-
- logo db CR,LF
- db 'LONGINT.DEM - Demo für die Routinen in LONGINT.LIB'
- db CR,LF
- db '--------------------------------------------------'
- db CR,LF
- db CR,LF
- GETLENGTH Logo
-
- PROMPT1 db
- db 'Bitte geben Sie die Rechenart ein (+,-,*,/,\,^ <CR> = '
- _opcode0 db '+, X, <ESC> = Ende): '
- GETLENGTH Prompt1
-
- PROMPT2 db
- db CR,LF
- db 'Rechenart: '
- _Opcode db 'A --> '
- db 'Bitte geben Sie den ersten Operanden ein: '
- GETLENGTH Prompt2
-
- PROMPT3 db
- db 'Rechenart: '
- _Opcode1 db 'A --> '
- db 'Bitte geben Sie den zweiten Operanden ein: '
- GETLENGTH Prompt3
-
- ResultMSG db
- db 'Das Ergebnis ist '
- Result db ' '
- db CR,LF
- GETLENGTH ResultMSG
-
- RestMSG db
- db 'Der Rest ist '
- Rest db ' '
- db CR,LF
- GETLENGTH RestMSG
-
- Error1 db 'Falsche Eingabe! (Eingabe zu groß oder Syntax falsch)'
- db CR,LF
- GETLENGTH Error1
-
- Error2 db 'Fehler beim Rechnen!'
- db CR,LF
- GETLENGTH Error2
-
- Op1 db 255,256 dup 0
- Op2 db 255,256 dup 0
-
- OpCode db '+'
-
- ; ----------------------------
-
- Start:
- call ShowLogo ; Logo ausgeben und Speicherblock verkleinern
-
- l0: ; Opcode ermitteln
- WRITE_STRING Prompt1
- l00:
- mov ah,08h
- int 021h
- cmp al,CR
- je >l10 ; alten Opcode nochmal benutzen
- cmp al,ESC
- if e mov al,'X'
-
- cmp al,'X' ; Eingabe auswerten
- if e jmp Ende ; Ende
- cmp al,'x'
- if e jmp Ende
- cmp al,'^'
- je >l1
- cmp al,'+'
- je >l1
- cmp al,'-'
- je >l1
- cmp al,'*'
- je >l1
- cmp al,'\'
- je >l1
- cmp al,'/'
- jne l00 ; Falsche Eingabe
- l1:
- mov Opcode,al ; Op-Code sichern
- mov _Opcode,al ; Op-Code in Meldungen eintragen
- mov _Opcode0,al
- mov _Opcode1,al
- l10:
- call ShowCR_LF
-
- l00: ; ersten Operanden lesen
- WRITE_STRING Prompt2
- mov dx,offset op1
- mov ah,0Ah
- int 021h
- call ShowCR_LF
-
- mov si,offset op1+2 ; Eingabe konvertieren
- call GetLongInt
- jnc >l1
- ; Falsche Eingabe
- WRITE_STRING error1
- jmp l00 ; Eingabe wiederholen
-
- l1:
- push cx,bx ; 1. Operanden sichern
-
- l01: ; zweiten Operanden lesen
- WRITE_STRING Prompt3
- mov dx,offset op2
- mov ah,0Ah
- int 021h
- call ShowCR_LF
- ; Eingabe konvertieren
- mov si,offset op2+2
- call GetLongInt
- jnc >l1
- ; Falsche Eingabe
- WRITE_STRING error1
- jmp l01 ; Eingabe wiederholen
-
- l1:
- ; 2. Operand steht in CX:BX
- pop ax,dx ; 1. Operand nach DX:AX
-
- cmp opcode, '+' ; Opcode auswerten und ausführen
- jne >l1
- call AddLongInt
- clc
- jmp >l2
- l1:
- cmp opcode, '-'
- jne >l1
- call SubLongInt
- clc
- jmp >l2
- l1:
- cmp opcode,'\'
- jne >l1
- call ModLongInt
- jmp >l2
- l1:
- cmp opcode, '/'
- jne >l1
- push ax,bx,cx,dx
- call DivLongInt ; Ergebnis ermitteln
- jc >l10 ; Fehler beim Dividieren!
- call ShowResult
- pop dx,cx,bx,ax
- call ModLongInt ; Rest ermitteln
- jc >l2
- call ShowRest
- jmp l0
-
- l10:
- pop dx,cx,bx,ax
- jmp >l2
-
- l1:
- cmp opcode,'^'
- jne >l1
- call CalcLongIntPotenz
- clc
- jmp >l2
- l1:
- call MulLongInt
- clc
- l2:
- jnc >l1
- ; Fehler bei der Berechnung
- WRITE_STRING error2
- jmp >l2
-
- l1: ; Ergebnis ausgeben
- Call ShowResult
- l2:
- jmp l0 ; und nächste Eingabe holen
-
- Ende:
- EndProcess 0
-
- ; ----------------------------
- ; GetLongInt
- ;
- ; Funktion: Konvertiert die Longint-Variable bei DS:SI nach CX:BX
- ;
- ; Ausgabe: CF = 0 -> okay
- ; CF = 1 -> Fehler
- ;
- GetLongint:
- push bp
- xor bp,bp ; BP = Vorzeichenmarker
- xor bx,bx
- xor cx,cx ; CX:BX = Ergebnis -> auf 0 setzen
-
- lodsb ; AL = erstes Zeichen
- cmp al,'+'
- je >l10 ; + ist Voreinstellung
- cmp al,'-'
- jne >l1
- mov bp,01 ; Marker für negativ setzen
- l10:
- lodsb ; AL = nächstes Zeichen
- l1:
- CALL DezDigit?
- jc GetLongIntError
- mov bl,al ; Ergebnis korrigieren
-
- GetLongInt0:
- lodsb ; AL = nächstes Zeichen
- cmp al,'.'
- je GetLongInt0 ; Punkte als Trenner erlaubt
-
- call DezDigit?
- jc GetLongIntOkay
-
- push ax ; alten Wert * 10
- mov ax,0Ah
- xor dx,dx
- call MulLongInt
- mov bx,ax
- mov cx,dx
- pop ax
-
- xor ah,ah ; neue Stelle aufaddieren
- add bx,ax
- adc cx,0
- or cx,cx
- js GetLongIntError
- jmp GetLongInt0 ; und nächstes Zeichen
-
- GetLongIntOkay:
- test ch,080h
- jnz GetLongIntError ; Wert zu groß!
- or bp,bp
- jz GetLongIntOkay1
- call ChangeSignCXBX ; Vorzeichen ändern
-
- GetLongIntOkay1:
- clc
- pop bp
- ret
-
- GetLongIntError:
- stc
- pop bp
- ret
-
- ; ----------------------------
- ; ShowResult
- ;
- ; Funktion: Ausgabe des Ergebnisses
- ;
- ; Eingabe: DX:AX = Ergebnis
- ;
- ShowResult:
- push bx
- push cx
- push dx
- push ax
- mov di,offset Result
-
- mov b sign,'+'
- or dx,dx ; Vorzeichen berücksichtigen
- jns >l1
- call changesigndxax ; Absolut-Wert ermitteln
- mov b sign,'-'
- l1:
-
- mov b v0,0
-
- mov cx,03b9Ah
- mov bx,0CA00h ; CX:BX = 1.000.000.000
- call StoreDezDigit1
-
- mov cx,05F5h ; CX:BX = 100.000.000
- mov bx,0E100h
- call StoreDezDigit1
-
- mov cx,098h ; CX:BX = 10.000.000
- mov bx,09680h
- call StoreDezDigit1
-
- mov cx,0Fh ; CX:BX = 1.000.000
- mov bx,04240h
- call StoreDezDigit1
-
- mov cx,01h
- mov bx,086A0h ; CX:BX = 100.000
- call StoreDezDigit1
-
- xor cx,cx ; CX:BX = 10.000
- mov bx,02710h
- call StoreDezDigit1
-
- xor cx,cx ; CX:BX = 1.000
- mov bx,03E8h
- call StoreDezDigit1
-
- xor cx,cx ; CX:BX = 100
- mov bx,064h
- call StoreDezDigit1
-
- xor cx,cx ; CX:BX = 10
- mov bx,0Ah
- call StoreDezDigit1
-
- mov bx,ax ; 1er
- cmp v0,0
- if z mov b v0,1
-
- call StoreDezDigit2
- ; Ergebnis ausgeben
- WRITE_STRING ResultMSG
-
- pop ax
- pop dx
- pop cx
- pop bx
- ret
-
- ; ----------------------------
- ; ShowRest
- ;
- ; Funktion: Gibt den Rest einer Division aus
- ;
- ; Eingabe: DX:AX = Rest
- ;
- ShowRest:
- push ax
- push bx
- push cx
- push dx
- mov di,offset Rest
-
- mov b sign,'+'
- or dx,dx ; Vorzeichen berücksichtigen
- jns >l1
- call changesigndxax ; Absolut-Wert ermitteln
- mov b sign,'-'
- l1:
-
- mov b v0,0
-
- mov cx,03b9Ah
- mov bx,0CA00h ; CX:BX = 1.000.000.000
- call StoreDezDigit1
-
- mov cx,05F5h ; CX:BX = 100.000.000
- mov bx,0E100h
- call StoreDezDigit1
-
- mov cx,098h ; CX:BX = 10.000.000
- mov bx,09680h
- call StoreDezDigit1
-
- mov cx,0Fh ; CX:BX = 1.000.000
- mov bx,04240h
- call StoreDezDigit1
-
- mov cx,01h
- mov bx,086A0h ; CX:BX = 100.000
- call StoreDezDigit1
-
- xor cx,cx ; CX:BX = 10.000
- mov bx,02710h
- call StoreDezDigit1
-
- xor cx,cx ; CX:BX = 1.000
- mov bx,03E8h
- call StoreDezDigit1
-
- xor cx,cx ; CX:BX = 100
- mov bx,064h
- call StoreDezDigit1
-
- xor cx,cx ; CX:BX = 10
- mov bx,0Ah
- call StoreDezDigit1
-
- mov bx,ax ; 1er
- cmp v0,0
- if z mov b v0,1
-
- call StoreDezDigit2
- ; Rest ausgeben
- WRITE_STRING RestMSG
- pop dx
- pop cx
- pop bx
- pop ax
- ret
-
- ; --------
- ; Unteroutine von ShowResult
- ;
- v0 db 0
- sign db '+'
-
- StoreDezDigit1:
- call DivLongInt ; Dividieren
- ; AL = Ergebnis
-
- StoreDezDigit2:
- add al,'0'
- cmp v0,2
- je >l1
- cmp v0,1
- je >l00
- cmp al,'0'
- je >l10
- l00:
- mov v0,2
- mov ah,sign
- mov [di],ah
- inc di
- l1:
- stosb
-
- mov dx,cx
- mov ax,bx ; Rest nach DX:AX
- ret
-
- l10:
- mov al,' '
- jmp l1
-
- ; ----------------------------
- ; DezDigit?
- ;
- ; Funktion: Wandelt das ASCII-Zeichen in AL in dessen binären Wert, falls
- ; es sich um eine Dezimal-Ziffer handelt. Im Fehlerfall wird das
- ; Carry-Flag gesetzt
- ;
- ; Eingabe: AL = ASCII-Zeichen
- ;
- ; Ausgabe: CF = 0 -> okay, AL = Wert
- ; CF = 1 -> Fehler, AL undefiniert
- ;
- DezDigit?:
- sub al,'0'
- cmp al,0Ah
- cmc
- ret
-
- ; ----------------------------
-
-