MOV DS,AX MOV AX,0 MOV ES,AX ;给数据段段基址赋初值 ;给附加数据段段基址赋初值 ;保存原中断向量表 MOV AX,WORD PTR ES:[0000H] PUSH AX MOV AX,WORD PTR ES:[0002H] PUSH AX ;写入新的中断处理子程序地址 MOV WORD PTR ES:[0000H],OFFSET INT0 ;0号中断子程序的偏移地址 MOV WORD PTR ES:[0002H],SEG INT0 ;0号中断子程序的基地址 CALL INPUT; 获取输入 MOV DX,WORD PTR dividend ;被除数的高16为放入DX ;被除数的低16位放入AX ;除数放入BX MOV AX,WORD PTR dividend+2 MOV BX,divisor DIV BX ;进行32位除法运算 CMP FLAG,0 ;查看是否调用了中断处理程序,即可判断是否溢出 JNE ISOF ;如果溢出标志FLAG不为0,则跳转到ISOF,进行输出商的输出位数的扩展 ; 否则直接输出没有溢出的正常除法结果 PRINT CHAR1 ;输出低16位AX中商的结果并显示 MOV BX,AX CALL DISPLAY2 PRINT CR PRINT CHAR2 ;输出高16位DX中余数的结果并显示 MOV BX,DX CALL DISPLAY2 JMP EOP ;显示完毕跳转到返回DOS ;有溢出的时候需要输出32位商和16位余数 ISOF: PRINT CHAR1 ;输出低32位AX、DX中商的结果并显示 MOV BX,DX CALL DISPLAY2 MOV BX,AX
CALL DISPLAY2 PRINT CR PRINT CHAR2 ;输出高16位CX中余数的结果并显示 MOV BX,CX CALL DISPLAY2 EOP: POP AX ;程序结束出口 ;恢复中断向量表 MOV WORD PTR ES:[0002H],AX POP AX MOV WORD PTR ES:[0000H],AX MOV AX,4C00H; 返回DOS INT 21H ;-------------------------------------------------------- ;修改完的新的0号中断子程序 INT0: POP SI ADD SI,2 ;修改IP的值,指向DIV后的指令 PUSH SI CMP BX,0 ;判断除数是否为0 JE ERROR0 ;为零则提示除数为0,然后返回DOS MOV FLAG,1 ;置标志为除数不为零溢出 ;进行扩展除法运算,分别用除数除以被除数高16位和低16位 ;输出参数为DX:商高16位,AX:商低16位,CX:16位余数 PUSH AX MOV AX,DX XOR DX,DX ;除前将DX清零 DIV BX ;高16位除法 MOV CX,AX ;保存商的高16位 POP AX ;取出被除数低16位 DIV BX ;低16位除法 XCHG CX,DX ;同时保存余数和商的低16位 JMP EXIT
ERROR0: PRINT ERR0 ;除数为0则打印错误提示并结束程序 MOV AX,4C00H ;返回DOS INT 21H EXIT:IRET ;-------------------------------------------------------- ;获取用户输入二进制序列的代码 INPUT PROC NEAR PUSH AX PRINT CHAR3 ;提示输入被除数的高16位 CALL GETCHAR ;调用获取一次输入缓冲,得到16位二进制码 CALL CHANGE ;对字符进行转换,得到二进制序列 MOV AX,TMP MOV WORD PTR dividend[0],AX ;保存被除数高16位 PRINT CR PRINT CHAR4 ;提示输入被除数的低16位 CALL GETCHAR CALL CHANGE MOV AX,TMP MOV WORD PTR dividend[2],AX ;保存被除数低16位 PRINT CR PRINT CHAR5 CALL GETCHAR CALL CHANGE MOV AX,TMP MOV divisor,AX ;保存除数 PRINT CR POP AX RET INPUT ENDP ;------------------------------------------------------- ;缓冲区0、1字符序列转换为二进制数子程序 CHANGE PROC NEAR
PUSH AX ;保护现场 PUSH BX PUSH CX PUSH DX MOV CX,16 ;总共16bit XOR BX,BX LOOP1: MOV AL,CHAR[BX] ;依次取出每个bit CMP AL,30H ;与0的ASCII码进行比较 JE ISZER ;是0的处理 JMP ISON ;是1的处理 ISZER: CLC RCL DX,1 ;把CF清0,然后循环左移,可得到二进制序列 JMP EXIT1 ISON: STC RCL DX,1 ;把CF置1,循环左移 EXIT1: INC BX LOOP LOOP1 ;把16bit输入处理完 MOV TMP,DX ;保存转换后的二进制数 POP DX ;恢复现场 POP CX POP BX POP AX RET CHANGE ENDP ;------------------------------------------------------- ;获取一次输入字符串缓冲子程序 GETCHAR PROC NEAR PUSH AX ;保护现场 PUSH DX PUSH DI MOV DX,OFFSET BUFF MOV AH,0AH INT 21H
POP DI ;恢复现场 POP DX POP AX RET GETCHAR ENDP ;------------------------------------------------------- ;显示二进制序列的子程序,把二进制数转换为0、1字符串输出 DISPLAY2 PROC NEAR PUSH CX MOV CX,16 START1: SHL BX,1 ; 二进制数左移到CF JNC ISZERO ; 判断CF是0还是1,分别打印之 PRINT ONE ;打印字符一 JMP ISONE ISZERO: PRINT ZER ;打印字符零 ISONE: LOOP START1 PRINT TAB POP CX RET DISPLAY2 ENDP ;------------------------------------------------------- CODE ENDS END MAIN
七、程序运行结果
程序运行结果如下图所示: