用子程序结构编程:从键盘输入一个十进制数,对其开平方后分别将其平方根和余数以十进制数的形式显示。
DATA SEGMENT
SUM DW 2 DUP(?)
BUF DB 7 DUP(?)
DATA ENDS
stack segment ;定义栈段,保存div的余数
dw 40 dup (?)
stack ends
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
START:MOV AX,DATA
MOV DS,AX
CMP AL,0DH
JE OUTIT
CALL DIB
OUTIT:MOV AX,BX
CALL SQUR
MOV SUM,CX
MOV SUM+2,AX
MOV AX,CX
CALL BID
MOV DL,',' ;显示‘,’
MOV AH,2
INT 21H
MOV AX,SUM+2
CALL BID
MOV AX,4C00H
INT 21H
; 有符号的二进制数(即十六进制数)转换为十进制数并显示。这里采用另一种方法来进行数制的转换:
; 将要转换的数存入AX中,先用AX 中值除10,得的余数就是个位数;再用上次得的商除10,得的余数
; 就是百位数;再用上次得的商除10,得的余数就是千位数;依次得每位十进制数压栈,直到商为0。
; 然后又依次出栈到缓冲区,在缓冲区中得到由高到低位的顺序并用显示字符串方式显示结果。
BID PROC NEAR
PUSH BX ;现场的保护
PUSH CX
PUSH DX
PUSH SI
LEA SI,BUF
OR AX,AX
JNS PLA1 ;正数可直接转换
NEG AX ;负数求补得绝对值
MOV BYTE PTR [SI],'-';存‘-’
INC SI
PLA1:MOV BX,10
MOV CX,0
REP2:MOV DX,0
DIV BX
PUSH DX ;余数压栈
INC CX ;位数计数
OR AX,AX
JNZ REP2 ;商不为0则循环
REP3:POP AX ;依次出栈到缓冲区
ADD AL,30H ;转换为ASCII码
MOV [SI],AL
INC SI
LOOP REP3
MOV BYTE PTR [SI],'$';结束符
LEA DX,BUF ;显示
MOV AH,9
INT 21H
POP SI ;现场的恢复
POP DX
POP CX
POP BX
RET
BID ENDP
; 键入十进制数转为十六进制数存在BX中。
; 从键盘输入的十进制数,实际上是得到十进制数字符的ASCII码,所以,首先要将十进制数字符
; 的ASCII码(30H~39H)转换为十进制数(0~9),再将其转换为十六进制数。
; 要将十进制数234转换为十六进制数,可用如下公式:234=((0*10+2)*10+3)*10+4完成。由于
; 计算机中的算术运算指令都是二进制数运算,所以,运算得的结果就是二进制数,即十六进制数。
DIB PROC NEAR
MOV BX,0
REP1: MOV AH,1
INT 21H
SUB AL,30H
JL EXIT
CMP AL,9
JG EXIT
CBW
XCHG AX,BX
MOV CX,10
MUL CX
ADD BX,AX
JMP REP1
EXIT: RET
DIB ENDP
; 将一个数开平方,平方根和余数分别存入SUM和SUM+2中
; 开平方的算法:N的平方等于N个自然奇数之和。N^2^=1+3+5+……+(2N–1)
; 从这个数中依次减去奇数1、3、5、…,至被开方数小于下一个奇数为止,累计减去奇数的个数就是S的整数平方根。减完剩下的值就是余数。
SQUR PROC NEAR
PUSH DX
MOV CX,0 ; 初始化平方根的值
MOV DX,1 ; 自然奇数的首项送DX
REP1: CMP AX,DX
JB EXIT
SUB AX,DX
INC CX
ADD DX,2
JMP REP1
EXIT: POP DX
RET
SQUR ENDP
CODE ENDS
END START