源程序:
.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