📄 div.s
字号:
;;-------------------------------------------------------+-----;; | GMD ;; PROC DIV VERSION 1.0 +-----;; DATE 15.10.87 ;; BY BOTT WOLFGANG ;; ;; ;; DESCRIPTION GANZZAHLIGE DIVISION VON ZWEI LANGEN ZAHLEN ;; OPERANDEN UND ERGEBNISFELDER DUERFEN GLEICH ;; SEIN. DABEI UEBERSCHREIBT GEGEBENENFALLS ;; DER REST DEN QUOTIENTEN ;; POINTER AUF DIE OPERANDEN SIND 4 BYTE LANG. ;; ;; IN DESCRIPTION ADR: ;; DIVIDENT ALS LANGE ZAHL [BP] + 6 ;; DIVISOR ALS LANGE ZAHL [BP] + 10 ;; ;; INOUT ;; ;; OUT ;; QUOTIENT ALS LANGE ZAHL [BP] + 14 ;; REST ALS LANGE ZAHL [BP] + 18 ;; ;;-------------------------------------------------------------;;include asmtoken.h; EXTRN _SSHIFT:NEAR;;--------------------------------------;; ;; BLOCKSTRUKTUR DEFINIEREN. ;; ;;--------------------------------------;;_TEXT SEGMENT BYTE PUBLIC 'CODE'_TEXT ENDS_DATA SEGMENT WORD PUBLIC 'DATA'_DATA ENDSCONST SEGMENT WORD PUBLIC 'CONST'CONST ENDS_BSS SEGMENT WORD PUBLIC 'BSS'_BSS ENDS;DGROUP GROUP _DATA,_BSS,CONSTASSUME CS:_TEXT,DS:DGROUP,SS:DGROUP,ES:DGROUP;;--------------------------------------;; ;; PROGRAMMTEXT: ;; ;; ZUERST REGISTER RETTEN. ;; ;;--------------------------------------;;_TEXT SEGMENTPUBLIC _DIV_DIV PROC FAR PUSH BP MOV BP,SP PUSH ES PUSH DI PUSH SI PUSH DS PUSH DS PUSH DS;; OPERAND1 VON FAR IN NEAR UMSPEICHERN; POP ES ; REP MOVS BEFEHL MOV DS,[BP+8] ; VORBEREITEN. MOV SI,[BP+6] ; SOURCE = DS:SI LEA DI,OPER1 ; DEST = ES:DI MOV CX,DS:[SI] ; COUNT = CX SAR CX,1 ADD CX,1 REP MOVSW;; OPERAND2 VON FAR IN NEAR UMSPEICHERN; MOV DS,[BP+12] MOV SI,[BP+10] LEA DI,OPER2 MOV CX,DS:[SI] SAR CX,1 ADD CX,1 REP MOVSW;; EIGNETLICHE DIVISION AUFRUFEN; POP DS POP ES LEA BX,[OPER4] PUSH BX LEA BX,[OPER3] PUSH BX LEA BX,[OPER2] PUSH BX LEA BX,[OPER1] PUSH BX CALL _SDIV;; ERGEBNIS VON NEAR IN FAR UMSPEICHERN; MOV ES,[BP+16] MOV DI,[BP+14] MOV CX,OPER3 SAR CX,1 ADD CX,1 LEA SI,OPER3 REP MOVSW;; REST VON NEAR IN FAR UMSPEICHERN; MOV ES,[BP+20] MOV DI,[BP+18] MOV CX,OPER4 SAR CX,1 ADD CX,1 LEA SI,OPER4 REP MOVSW ADD SP,8 POP SI POP DI POP ES MOV SP,BP POP BP RET_DIV ENDP_SDIV PROC NEAR;;--------------------------------------;; EIGENTLICHES SUBTRAKTIONSPROGRAMM. ;; DIE POINTER AUF DIE OPERANDEN SIND ;; JETZT ALLE 'NEAR'. ;; ;; ADRESSEN DER PARAMETER: ;; ;; DIVIDENT: 4 + (BP) ;; DIVISOR: 6 + (BP) ;; QUOTIENT: 8 + (BP) ;; REST: 10 + (BP) ;; ;;--------------------------------------;;;;--------------------------------------;; ;; LOKALE VARIABLEN: ;; ;; DIVIDENT : EIN FELD, IN DEM DER ;; REST BERECHNET WIRD ;; SFAKTOR : ERWEITERUNGSFAKTOR ;; TEST : EINE ZIFFER DES TESTFELDES;; ZQUOT : AKTUELLE ZIFFER DES ;; QUOTIENTEN, DER IM FELD ;; QUOTIENT : BERECHNET WIRD ;; FIRSTDIGIT : ERSTE ZIFFER DES ;; DIVISORS ;; ;; **** VORSICHT **** ;; ;; DIE ARBEITSFELDER 'DIVIDENT' UND ;; 'QUOTIENT' MUESSEN LANG GENUG SEIN, ;; UM DIE OPERANDEN AUFNEHMEN ZU ;; KOENNEN. ;; DIESE LAENGE IST IN DER DATEI ;; RSANUMBER.H DEFINIERT. ;; ;;--------------------------------------;;;;--------------------------------------;; ;; ZUERST REGISTER RETTEN. ;; ;;--------------------------------------;; PUSH BP MOV BP,SP PUSH DI PUSH SI;;--------------------------------------;; ;; SONDERFAELLE BEARBEITEN: ;; ;; DIVISION DURCH NULL? ;; ;;--------------------------------------;; MOV BX,[6+BP] ; ADRESSE DES ; DIVISORS CMP WORD PTR [BX],0 JNE NOERROR ; DIVISOR <> 0 ? MOV AX,-1 ; C-RETURNCODE JMP RETURN;;--------------------------------------;; ;; DIVIDENT KLEINER ALS DIVISOR? ;; ;;--------------------------------------;;NOERROR: MOV SI,[4+BP] ; ADRESSE DIVIDENT MOV CX,[SI] ; LAENGE DIVIDENT CMP CX,[BX] ; LAENGENVERGLEICH JGE NOTTRIVIAL MOV BX,[8+BP] ; QUOTIENT = 0 MOV WORD PTR [BX],0 MOV DI,[10+BP] ; REST = DIVIDENT MOV [DI],CX ; LAENGENFELD DES ; DIVIDENTEN ; KOENNTE UEBER- ; SCHRIEBEN WORDEN ; SEIN ADD DI,2 ; 'REP MOVS'-BEFEHL ADD SI,2 ; VORBEREITEN SHR CX,1 REP MOVSW XOR AX,AX ; RETURNCODE = 0 JMP RETURN;;--------------------------------------;; ;; HAT DER DIVISOR NUR EINE ZIFFER? ;; ;;--------------------------------------;;NOTTRIVIAL: CMP WORD PTR [BX],2 JNE NOTSHORT;;--------------------------------------;; ;; DIVISION DURCH EINE EINSTELLIGE ;; ZAHL IST LEICHT: ;; ;;--------------------------------------;; MOV CX,[2+BX] ; ZIFFER DES ; DIVISORS LADEN MOV DI,[SI] ; LAENGE DES DIVI- ; DENTEN LADEN MOV BX,SI ; ADRESSE DIVIDENT PUSH BP ; 'BP' RETTEN MOV BP,[8+BP] ; ADRESSE QUOTIENT XOR DX,DX ; HOCHWERTIGER ; TEIL DES ; DOPPELREGISTERS ; LOESCHENLOOPSDIV: MOV AX,[BX+DI] ; ZIFFER DES DIVI- ; DENTEN LADEN DIV CX ; DIVIDIEREN MOV [BP+DI],AX ; ZIFFER DES QUO- ; TIENTEN SPEICHERN SUB DI,2 ; INDEX FORTSCHALTEN JNZ LOOPSDIV MOV DI,[SI] ; LAENGE DES QUO- ; TIENTEN BESTIMMEN CMP WORD PTR [BP+DI],0 JNE NOCORRQ1 SUB DI,2NOCORRQ1: MOV [BP],DI ; LAENGE EINTRAGEN POP BP ; 'BP' VOM STACK ; HOLEN MOV BX,[10+BP] ; REST BESTEHT AUS CMP DX,0 ; EINER ZIFFER JNE NOTZERO ; DIESE KANN ABER ; NULL SEIN MOV WORD PTR [BX],0 XOR AX,AX ; RETURNCODE = 0 JMP RETURNNOTZERO: MOV [2+BX],DX MOV WORD PTR [BX],2 XOR AX,AX ; RETURNCODE = 0 JMP RETURN;;--------------------------------------;; ;; ECHTE DIVISION MUSS DURCHGEFUEHRT ;; WERDEN. ;; ERSTER SCHRITT: UEBERTRAGEN DES ;; DIVIDENTEN IN EIN ARBEITSFELD ;; ;;--------------------------------------;;NOTSHORT: LEA DI,DIVIDENT SHR CX,1 INC CX REP MOVSW;;--------------------------------------;; ;; ZWEITER SCHRITT: ERWEITERN VON ;; DIVISOR UND DIVIDENT ;; ;;--------------------------------------;; MOV SI,[BX] ; HOECHSTWERTIGSTE MOV AX,[BX+SI] ; ZIFFER DES ; DIVISORS LADEN AND AX,AX ; HOECHSTWERTIGSTES JNS SHIFT ; BIT BELEGT ? MOV SFAKTOR,0 ; DANN KEIN SHIFTEN JMP STARTDIVSHIFT: XOR CX,CX ; SHIFTFAKTOR BESTIM-LOOPSHIFT: ; MEN DURCH SHIFTEN INC CX ; NACH LINKS SHL AX,1 ; NACH LINKS JNS LOOPSHIFT MOV SFAKTOR,CX ; SHIFTFAKTOR ; SPEICHERN LEA DX,DIVIDENT ; UNTERPROGRAMM PUSH DX ; 'SHIFT' FUER DEN PUSH CX ; DIVIDENTEN AUF- PUSH DX ; RUFEN CALL _SSHIFT
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -