源程序:
.386
CODE SEGMENT USE16
ASSUME CS:CODE,DS:CODE
ORG 100H
START:
JMP INSTALL
HANDLE DW ?
_MIN DW ?
_SEC DW ?
_SEC1 DW ?
_A DD ?
_B DD ?
_FS_POINT DW 0
_GS_POINT DW 0
_DIV DD 1
FLAG DB ? ;=1 +
DIGITAL DD 5000 ;how many points want to calculate
POINT DW ? ;total point /5
NUM_POINT DW ? ;total point /5 * 4
_COUNT DD ?
TMP_NUM0 DD ?
TMP_NUM DD 10 DUP (?)
KEY_BUFF DB 6,0,6 DUP (0)
D_SAVE DB 'Saving result to file %c ...',0
DW 80H
D_SAVE_OK DB 8,8,8,8,', OK !',0DH,0AH,0
D_SAVE_ERR DB 8,8,8,8,', error !',0DH,0AH,0
D_TIME DB 0DH,0AH,'Total %ld points, time used %d:%02d.%03d, '
DB 'calculate %ld times.',0DH,0AH,0
DW DIGITAL,_MIN,_SEC,_SEC1,_DIV
D_SCAN DB '<> Dec 18, 1996',0DH,0AH
DB 'Copyright(C) by Luo Yun Bin, phone 0576-4114689',0DH,0AH,0AH
DB 'How many points (10-80000): ',0
D_ABORT DB 'User pressed Esc, calculate aborted !%20r ',0DH,0AH,0
D_CAL DB 'Calculating, please waiting ... (Esc to cancel)',0DH,0
D_CAL1 DB '%d %% calculated, please waiting ... (Esc to cancel)',0DH,0
DW PERCENT
PERCENT DW ?
D_STR1 DB ' PI = %1ld.%c',0DH,0AH,0
DW TMP_NUM0,D_SUB_STR
D_STR2 DB '%5ld : %c'
DB 0DH,0AH,0
DW _COUNT,D_SUB_STR
D_SUB_STR DB '%05ld %05ld %05ld %05ld %05ld '
DB '%05ld %05ld %05ld %05ld %05ld',0
DW TMP_NUM,TMP_NUM+4,TMP_NUM+8,TMP_NUM+12,TMP_NUM+16
DW TMP_NUM+20,TMP_NUM+24,TMP_NUM+28,TMP_NUM+32,TMP_NUM+36
INSTALL:
MOV SI,OFFSET D_SCAN
CALL PRINTF
MOV AH,0AH
MOV DX,OFFSET KEY_BUFF
INT 21H
MOV SI,OFFSET KEY_BUFF+2
CALL SCANF
MOV EAX,DWORD PTR SCAN_NUM
MOV DIGITAL,EAX
MOV SI,OFFSET D_CAL
CALL PRINTF
XOR AX,AX
MOV DS,AX
MOV AX,DS:[046CH]
PUSH CS
POP DS
MOV _SEC,AX
MOV AX,CS
ADD AX,1000H ;result of 4*4*5/25^n
MOV FS,AX
ADD AX,1000H ;result of 4*239/57121^n
MOV GS,AX
ADD AX,1000H ;total result
MOV BP,AX
MOV AX,FS
CALL INIT_NUM
MOV DWORD PTR FS:[4],4*239*100000
MOV AX,GS
CALL INIT_NUM
MOV DWORD PTR GS:[4],4*4*5*100000
MOV AX,BP
CALL INIT_NUM
CALL PRE
CALL CALC
XOR AX,AX
MOV DS,AX
MOV AX,DS:[046CH]
PUSH CS
POP DS
MOV _SEC1,AX
PUSH POINT
CALL NUM_OUT
POP POINT
MOV AX,_SEC1
SUB AX,_SEC
MOV CX,55
MUL CX
MOV CX,1000
DIV CX
MOV _SEC1,DX
MOV CX,60
XOR DX,DX
DIV CX
MOV _MIN,AX
MOV _SEC,DX
MOV SI,OFFSET D_TIME
CALL PRINTF
MOV SI,81H
MOV DI,80H
CMD_LOP:
LODSB
CMP AL,0DH
JZ CMD_END
CMP AL,20H
JBE CMD_LOP
CMP AL,'a'
JB CMD_STORE
CMP AL,'z'
JA CMD_STORE
SUB AL,20H
CMD_STORE:
STOSB
JMP SHORT CMD_LOP
CMD_END:
XOR AL,AL
STOSB
MOV SI,80H
CMP BYTE PTR DS:[SI],0
JZ QUIT
MOV SI,OFFSET D_SAVE
CALL PRINTF
MOV AH,3CH
XOR CX,CX
MOV DX,80H
INT 21H
JB FILE_ERR
MOV HANDLE,AX
MOV STD_OUT,OFFSET WRITE_FILE
CALL NUM_OUT
MOV STD_OUT,OFFSET PRT_TO_SCR
MOV SI,OFFSET D_SAVE_OK
CALL PRINTF
MOV AH,3EH
MOV BX,HANDLE
INT 21H
INT 20H
FILE_ERR:
MOV SI,OFFSET D_SAVE_ERR
CALL PRINTF
INT 20H
QUIT:
INT 20H
WRITE_FILE PROC
PUSHA
MOV AH,40H
MOV FLAG,AL
MOV BX,HANDLE
MOV CX,1
MOV DX,OFFSET FLAG
INT 21H
POPA
RET
WRITE_FILE ENDP
PRE PROC
MOV EAX,DIGITAL ;total 65536*5/4 points
CMP EAX,(65536/4-3)*5 ;comp max points
JBE PRE_1
MOV EAX,(65536/4-3)*5
PRE_1:
CMP EAX,10 ;comp min points
JAE PRE_2 ;must > 10 and < 81915
MOV EAX,10
PRE_2:
XOR EDX,EDX
MOV ECX,5
DIV ECX
MOV EBX,EAX
INC EBX
MOV POINT,BX ;point for print control
MUL ECX
MOV DIGITAL,EAX ;
MOV EAX,EBX
INC EAX
MOV ECX,4
MUL ECX
MOV NUM_POINT,AX ;max used memory
RET
PRE ENDP
CALC PROC
MOV ES,BP
C_LOP0:
MOV AH,1
INT 16H
JZ CALC_0
XOR AH,AH
INT 16H
CMP AL,1BH
JNZ CALC_00
PUSH CS
POP ES
MOV SI,OFFSET D_ABORT
CALL PRINTF
INT 20H
CALC_00:
XOR EAX,EAX
MOV AX,_GS_POINT
MOV ECX,500
MUL ECX
MOV ECX,4
DIV ECX
XOR EDX,EDX
DIV DIGITAL
MOV PERCENT,AX
MOV SI,OFFSET D_CAL1
PUSH CS
POP ES
CALL PRINTF
MOV ES,BP
CALC_0:
XOR EAX,EAX
MOV ECX,100000
MOV _A,EAX
MOV _B,EAX
XOR FLAG,00000001B ;init part
;============================================================
MOV EBX,57121
C_LOP1:
MOV SI,_FS_POINT ;if 4*5/25^n = 0 skip
CMP SI,NUM_POINT
JAE CALC_1
CMP DWORD PTR FS:[SI],0
JNZ C_LOP2
ADD _FS_POINT,4
JMP SHORT C_LOP1
C_LOP2:
MUL ECX
ADD EAX,FS:[SI]
ADC EDX,0
DIV EBX
MOV FS:[SI],EAX
MOV EAX,EDX
ADD SI,4
CMP SI,NUM_POINT
JB C_LOP2
;=======================================================
CALC_1:
MOV EBX,25
C_LOP3:
MOV SI,_GS_POINT ;if 4*5/25^n = 0 skip
CMP SI,NUM_POINT
JAE CALC_4
CMP DWORD PTR GS:[SI],0
JNZ C_LOP4
ADD _GS_POINT,4
JMP SHORT C_LOP3
C_LOP4:
MOV EAX,_A
MUL ECX
ADD EAX,GS:[SI]
ADC EDX,0
DIV EBX
MOV GS:[SI],EAX
MOV _A,EDX
MOV EAX,_B
MUL ECX
ADD EAX,GS:[SI]
ADC EDX,0
SUB EAX,FS:[SI]
SBB EDX,0
CMP EDX,0
JL _T1
DIV _DIV
MOV _B,EDX
JMP SHORT _T2
_T1:
IDIV _DIV
DEC EAX
ADD EDX,_DIV
MOV _B,EDX
_T2:
TEST FLAG,00000001B
JNZ CALC_2
SUB ES:[SI],EAX
JMP SHORT CALC_3
CALC_2:
ADD ES:[SI],EAX
CALC_3:
ADD SI,4
CMP SI,NUM_POINT
JB C_LOP4
C_LOP5:
ADD _DIV,2
JMP C_LOP0
;====================================================
CALC_4:
XOR EAX,EAX
MOV _A,EAX
MOV SI,NUM_POINT
C_LOP6:
SUB SI,4
MOV EAX,ES:[SI]
ADD EAX,_A
CMP EAX,ECX
JGE CALC_5
CMP EAX,0
JLE CALC_6
MOV _A,0
MOV ES:[SI],EAX
JMP SHORT CALC_8
CALC_5:
XOR EDX,EDX
DIV ECX
MOV ES:[SI],EDX
MOV _A,EAX
JMP SHORT CALC_8
CALC_6:
MOV EDX,-1
IDIV ECX
DEC EAX
ADD EDX,ECX
MOV ES:[SI],EDX
MOV _A,EAX
CALC_8:
CMP SI,4
JA C_LOP6
MOV EAX,_A
MOV ES:[0],EAX
PUSH CS
POP ES
RET
CALC ENDP
INIT_NUM PROC
PUSH ES
MOV ES,AX
XOR EAX,EAX
CLD
XOR DI,DI
MOV CX,65536/4
CLD
REP STOSD
POP ES
RET
INIT_NUM ENDP
NUM_OUT PROC
CLD
XOR ESI,ESI
MOV _COUNT,ESI
MOV DI,OFFSET TMP_NUM0
MOV CX,11
CMP CX,POINT
JBE NO_ADJUST
MOV CX,POINT
NO_ADJUST:
SUB POINT,CX
MOV DS,BP
REP MOVSD
PUSH CS
POP DS
PUSH SI
MOV SI,OFFSET D_STR1
CALL PRINTF
POP SI
NO_LOP:
CMP POINT,0
JLE NO_QUIT
MOV CX,10
MOV DI,OFFSET TMP_NUM
XOR EAX,EAX
REP STOSD
MOV CX,10
MOV DI,OFFSET TMP_NUM
CMP POINT,10
JAE NO1
MOV CX,POINT
NO1:
SUB POINT,CX
ADD _COUNT,50
MOV DS,BP ;bp = result segment
REP MOVSD
PUSH CS
POP DS
PUSH SI
MOV SI,OFFSET D_STR2
CALL PRINTF
POP SI
JMP SHORT NO_LOP
NO_QUIT:
RET
NUM_OUT ENDP
INCLUDE SCANF.ASM
INCLUDE PRINTF.ASM
CODE ENDS
END START