windows的计算器是一个神奇的工具。。
回复 11楼 zklhp
此话 是 何意??? 不是很懂耶~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
程序代码:GAIXIE MACRO P1,P2,P3,P4,P5,P6
P2: CMP BYTE PTR [SI],P3
JB P5
CMP BYTE PTR [SI],P4
JNB P5
CMP BYTE PTR [SI],'$'
JZ P6
P1 BYTE PTR [SI],20H
P5: INC SI
LOOP P2
P6: LEA DX,BUF1+2
MOV AH,9
INT 21H
LEA DX,BF
MOV AH,9
INT 21H
JMP START
ENDM
DATA SEGMENT
BUF DB '**********choose the operation**********',0DH,0AH
DB '1:big to small',0DH,0AH
DB '2:small to big',0DH,0AH
DB '3:hexadecimal to binary',0DH,0AH
DB '4:binary to hexadecimal',0DH,0AH
DB '5:hexadecimal to decimal',0DH,0AH
DB '6:decimal to hexadecimal',0DH,0AH
DB '7:EXIT',0DH,0AH,'$'
BF DB 0DH,0AH,'$'
BUF1 DB 21,?,20 DUP(?) ;用来存放输入的字符串
BUF2 DB 'enter a hex data:$'
BUF3 DB 'The input is wrong,choose again please:$'
BUF4 DB 'enter a deci data:$'
BUF5 DB 'enter a bin data:$'
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
START:MOV AX,DATA
MOV DS,AX
MOV DX,OFFSET BUF ;出选择界面
MOV AH,9 ;调用9号中断功能
INT 21H
MOV AH,1 ;入要选择的操作
INT 21H
PUSH AX ;NT 会改变AL的值,应压栈保护
LEA DX,BF ;行
MOV AH,9 ;调用9号中断功能
INT 21H
POP AX ;把AX压栈保护
CMP AL,'1' ;把AL中内容跟1比较
JZ BTOS ;相等则跳转到
CMP AL,'2'
JZ STOB
CMP AL,'3'
JZ HTOB
CMP AL,'4'
JZ BTOH
CMP AL,'5'
JZ HTOD
CMP AL,'6'
JZ DTOH
CMP AL,'7'
JZ EXIT
LEA DX,BUF3 ;把BUF3的首地址给DX
MOV AH,9
INT 21H
CALL CRLF ;调用子程序CALL
JMP START ;返回,重新选择
EXIT:MOV AH,4CH ;退出
INT 21H
BTOH:CALL BETOHE ;调用二进制转十六进制子程序
HTOB:CALL BINARY ;调用十六进制转二进制子程序
HTOD:CALL HEXIDEC ;调用十六进制转十进制子程序
DTOH:CALL DETOHE ;调用十进制转十六进制子程序
BTOS:CALL INPUT ;大写字母改为小写
MOV CX,20 ;作为循环条件
GAIXIE ADD,NEXT1,'A','Z',N1,N2 ;宏GAIXIE展开
STOB:CALL INPUT ;小写字母改为大写
MOV CX,20
GAIXIE SUB,NEXT2,'a','z',N3,N4
INPUT PROC NEAR ;输入字符串
MOV DX,0 ;DX清零
MOV DX,OFFSET BUF1 ;把BUF1的首地址给DX
MOV AH,10 ;调用10号中断功能,输出字符串
INT 21H
LEA DX,BF ;把BF首地址给DX
MOV AH,9
INT 21H
LEA SI,BUF1+2
MOV BL,[SI-1] ;把输入的字符个数给BL
MOV BH,0 ;BH清零
MOV BYTE PTR [BX+SI+1],'$' ;把$作为字符串结束字符
LEA DX,BUF1+2
MOV AH,9
INT 21H
RET ;返回
INPUT ENDP
HEXIDEC PROC NEAR ;用该子程序把一个十六进制数转换成十进制数表示
PUSH DS ;保护初始数据段
SUB AX,AX ;AX清零
PUSH AX ;把AX压栈保护
START1: LEA DX,BUF2
MOV AH,9
INT 21H
CALL HEXIBIN ;调用输入一个十六进制数子程序
CMP AL,1BH ;遇Esc则退出
JZ EXIT1
CALL CRLF ;换行
CALL BINIDEC
CALL CRLF
JMP START1 ;返回
EXIT1:RET
HEXIDEC ENDP
HEXIBIN PROC NEAR ;输入一个十六进制数,并存放在BX中
MOV BX,0 ;把BX清零
MOV DX,0 ;作为输入四位的记数器
INHEX:CMP DX,4 ;把DX跟4比较
JNB HEXEND ;大于则跳转
MOV AH,1 ;输入数据
INT 21H
CMP AL,1BH ;遇到Esc则退出
JZ HEXEND
SUB AL,30H ;判断是否数字或字母?否则跳出
JL HEXEND
CMP AL,10 ;判断是否数字
JL ADD_TO ;是则存放BX中
SUB AL,7 ;把AL内容减7转为字母
CMP AL,10 ;判断是否小写字母(a~f)
JL HEXEND
CMP AL,16
JL ADD_TO ;小于则跳转
SUB AL,20H ;判断是否大写字母(A~F)
CMP AL,10
JL HEXEND
CMP AL,16
JGE HEXEND
ADD_TO:MOV CL,4 ;作为循环条件
SHL BX,CL ;BX乘以16
MOV AH,0
ADD BX,AX ;两数相加
INC DX ;DX加1
JMP INHEX
HEXEND:RET
HEXIBIN ENDP
BINIDEC PROC NEAR ;用来把BX中十六进制转换到十进制
MOV CX,10000 ;把10000给CX,作为万位的权
CALL DEC_DIV ;调用除权子程序
MOV CX,1000
CALL DEC_DIV
MOV CX,100
CALL DEC_DIV
MOV CX,10
CALL DEC_DIV
MOV CX,1
CALL DEC_DIV
RET
BINIDEC ENDP
DEC_DIV PROC NEAR ;除以各位十进制的权
MOV AX,BX ;把BX内容给AX
MOV DX,0 ;DX清零
DIV CX
MOV BX,DX
MOV DL,AL
ADD DL,30H ;转换为ASSII
MOV AH,2
INT 21H
RET
DEC_DIV ENDP
CRLF PROC NEAR ;换行
LEA DX,BF
MOV AH,9
INT 21H
RET
CRLF ENDP
BINARY PROC NEAR ;该子程序用来把十六制数转换为十六位二进制数表示
START2:LEA DX,BUF2
MOV AH,9
INT 21H
PUSH DS ;把DS压栈
SUB AX,AX ;AX清零
PUSH AX
CALL HEXIBIN
CMP AL,1BH
JZ EXIT2
CALL CRLF
CALL PRINT
CALL CRLF
JMP START2
EXIT2:RET
BINARY ENDP
PRINT PROC NEAR ;把BX中的十六进制数转换成二进制
MOV CX,16D ;记数
ROT: SHL BX,1D ;每移一位最高位变为CF
JC SET ;CF为1则跳到SET,否则输出0
MOV DL,30H
MOV AH,2
INT 21H
DEC CX
JNZ ROT
RET
SET:MOV DL,31H ;输出1
MOV AH,2
INT 21H
DEC CX
JNZ ROT
RET
PRINT ENDP
DETOHE PROC NEAR ;用该子程序来把一个十进制数转换成十六进制表示
REPEAT:LEA DX,BUF4
MOV AH,9
INT 21H
PUSH DS
SUB AX,AX
PUSH AX
CALL DECIBIN
CMP AL,1BH
JZ EXIT3
CALL CRLF
CALL BINIHEX
CALL CRLF
JMP REPEAT
EXIT3:RET
DETOHE ENDP
DECIBIN PROC NEAR ;输入一个五位的十进制数
MOV BX,0
MOV CX,0
NEWCHAR:CMP CX,5
JNB EXIT4
MOV AH,1
INT 21H
CMP AL,1BH
JZ EXIT4
SUB AL,30H
JL EXIT4
CMP AL,9
JG EXIT4
CBW
INC CX
XCHG AX,BX
MOV DX,10
MUL DX
XCHG AX,BX
ADD BX,AX
JMP NEWCHAR
EXIT4:RET
DECIBIN ENDP
BINIHEX PROC NEAR ;把BX中的十进制数转换成十六进制输出
MOV CH,4
ROTATE:MOV CL,4
ROL BX,CL ;把BX中高四位移到低四位,放到AL中
MOV AL,BL
AND AL,0FH
ADD AL,30H
CMP AL,3AH ;判断是否为数字
JL PRINTIT
ADD AL,7
PRINTIT:MOV DL,AL
MOV AH,2
INT 21H
DEC CH
JNZ ROTATE
RET
BINIHEX ENDP
BETOHE PROC NEAR ;用该子程序来把一个十六位二进制数转换成十六进制输出
START3:LEA DX,BUF5
MOV AH,9
INT 21H
PUSH DS
SUB AX,AX
PUSH AX
CALL INBIN
CMP AL,1BH
JZ EXIT5
CALL CRLF
CALL BINIHEX
CALL CRLF
JMP START3
EXIT5:RET
BETOHE ENDP
INBIN PROC NEAR ;输入十六二进制数
MOV BX,0
MOV CX,0
PUTIN:CMP CX,16
JNB EXIT6
MOV AH,1
INT 21H
CMP AL,1BH
JZ EXIT6
SUB AL,30H
JL EXIT6
CMP AL,1
JG EXIT6
CBW
INC CX
XCHG AX,BX
MOV DX,2
MUL DX
XCHG AX,BX
ADD BX,AX
JMP PUTIN
EXIT6:RET
INBIN ENDP
CODE ENDS
END START
程序代码:
GAIXIE MACRO P1,P2,P3,P4,P5,P6
P2: CMP BYTE PTR [SI],P3
JB P5
CMP BYTE PTR [SI],P4
JNB P5
CMP BYTE PTR [SI],'$'
; 到$则结束
JZ P6
P1 BYTE PTR [SI],20H
P5: INC SI
LOOP P2
P6: LEA DX,BUF 1+2
;出改写后的字母
MOV AH,9
; 调用9号中断功能,输出字符串
INT 21H
LEA DX,BF
; 把BF首地址给CX
MOV AH,9
; 调用9号中断功能
INT 21H
JMP START
; ;返回
ENDM
DATA SEGMENT
;义数据段
BUF DB '**********choose the operation**********',0DH,0AH
DB '1:big to small',0DH,0AH
DB '2:small to big',0DH,0AH
DB '3:hexadecimal to binary',0DH,0AH
DB '4:binary to hexadecimal',0DH,0AH
DB '5:hexadecimal to decimal',0DH,0AH
DB '6:decimal to hexadecimal',0DH,0AH
DB '7:EXIT',0DH,0AH,'$'
BF DB 0DH,0AH,'$'
buf1 db 21,?,20 dup(?)
;用来存放输入的字符串
BUF2 DB 'enter a hex data:$'
BUF3 DB 'The input is wrong,choose again please:$'
BUF4 DB 'enter a deci data:$'
BUF5 DB 'enter a bin data:$'
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
START: MOV AX,DATA
MOV DS,AX
MOV DX,OFFSET BUF
; 出选择界面
MOV AH,9
; 调用9号中断功能
INT 21H
MOV AH,1
; 入要选择的操作
INT 21H
PUSH AX
; NT 会改变AL的值,应压栈保护
LEA DX,BF
; 行
MOV AH,9
; 调用9号中断功能
INT 21H
POP AX
; 把AX压栈保护
CMP AL,'1'
; 把AL中内容跟1比较
JZ BTOS
; 相等则跳转到
CMP AL,'2'
JZ STOB
CMP AL,'3'
JZ HTOB
CMP AL,'4'
JZ BTOH
CMP AL,'5'
JZ HTOD
CMP AL,'6'
JZ DTOH
CMP AL,'7'
JZ EXIT
LEA DX,BUF3
; 把BUF3的首地址给DX
MOV AH,9
INT 21H
CALL CRLF
; 调用子程序CALL
JMP START
; 返回,重新选择
EXIT: MOV AH,4CH
;退出
INT 21H
BTOH: CALL BETOHE
;调用二进制转十六进制子程序
HTOB: CALL BINARY
;调用十六进制转二进制子程序
HTOD: CALL HEXIDEC
;调用十六进制转十进制子程序
DTOH: CALL DETOHE
;调用十进制转十六进制子程序
BTOS: CALL INPUT
;大写字母改为小写
MOV CX,20
; 作为循环条件
GAIXIE ADD,NEXT1,'A','Z',N1,N2
; 宏GAIXIE展开
STOB: CALL INPUT
;小写字母改为大写
MOV CX,20
GAIXIE SUB, NEXT2, 'a', 'z', N3, N4
INPUT PROC NEAR
;输入字符串
MOV DX,0
; DX清零
MOV DX,OFFSET BUF1
; 把BUF1的首地址给DX
MOV AH,10
; 调用10号中断功能,输出字符串
INT 21H
LEA DX,BF
; 把BF首地址给DX
MOV AH,9
INT 21H
LEA SI,BUF1+2
MOV BL,[SI-1]
; 把输入的字符个数给BL
MOV BH,0
; BH清零
MOV BYTE PTR [BX+SI+1],'$'
; 把$作为字符串结束字符
LEA DX,BUF1+2
MOV AH,9
INT 21H
RET
;返回
INPUT ENDP
HEXIDEC PROC NEAR
;用该子程序把一个十六进制数转换成十进制数表示
PUSH DS
; 保护初始数据段
SUB AX,AX
; AX清零
PUSH AX
; 把AX压栈保护
START1: LEA DX,BUF2
MOV AH,9
INT 21H
CALL HEXIBIN
; 调用输入一个十六进制数子程序
CMP AL,1BH
; 遇Esc则退出
JZ EXIT1
CALL CRLF
; 换行
CALL BINIDEC
CALL CRLF
JMP START1
; 返回
EXIT1: RET
HEXIDEC ENDP
HEXIBIN PROC NEAR
;输入一个十六进制数,并存放在BX中
MOV BX,0
; ;把BX清零
MOV DX,0
; 作为输入四位的记数器
INHEX: CMP DX,4
;把DX跟4比较
JNB HEXEND
; ;大于则跳转
MOV AH,1
; 输入数据
INT 21H
CMP AL,1BH
; 遇到Esc则退出
JZ HEXEND
SUB AL,30H
; 判断是否数字或字母?否则跳出
JL HEXEND
; JL HEXEND
CMP AL,10
; 判断是否数字
JL ADD_TO
; 是则存放BX中
SUB AL,7
; 把AL内容减7转为字母
CMP AL,10
; 判断是否小写字母(a~f)
JL HEXEND
CMP AL,16
JL ADD_TO
; 小于则跳转
SUB AL,20H
; 判断是否大写字母(A~F)
CMP AL,10
JL HEXEND
CMP AL,16
JGE HEXEND
ADD_TO: MOV CL,4
;作为循环条件
SHL BX,CL
; BX乘以16
MOV AH,0
ADD BX,AX
; 两数相加
INC DX
; DX加1
JMP INHEX
HEXEND: RET
HEXIBIN ENDP
BINIDEC PROC NEAR
;用来把BX中十六进制转换到十进制
MOV CX,10000
; 把10000给CX,作为万位的权
CALL DEC_DIV
; 调用除权子程序
MOV CX,1000
CALL DEC_DIV
MOV CX,100
CALL DEC_DIV
MOV CX,10
CALL DEC_DIV
MOV CX,1
CALL DEC_DIV
RET
BINIDEC ENDP
DEC_DIV PROC NEAR
;除以各位十进制的权
MOV AX,BX
; 把BX内容给AX
MOV DX,0
; DX清零
DIV CX
MOV BX,DX
MOV DL,AL
ADD DL,30H
;转换为ASSII
MOV AH,2
INT 21H
RET
DEC_DIV ENDP
CRLF PROC NEAR ;换行
LEA DX,BF
MOV AH,9
INT 21H
RET
CRLF ENDP
BINARY PROC NEAR
;该子程序用来把十六制数转换为十六位二进制数表示
START2: LEA DX,BUF2
MOV AH,9
INT 21H
PUSH DS
;把DS压栈
SUB AX,AX
;AX清零
PUSH AX
CALL HEXIBIN
CMP AL,1BH
JZ EXIT2
CALL CRLF
CALL PRINT
CALL CRLF
JMP START2
EXIT2:RET
BINARY ENDP
PRINT PROC NEAR
;把BX中的十六进制数转换成二进制
MOV CX,16D
;记数
ROT: SHL BX,1D
;每移一位最高位变为CF
JC SET
;CF为1则跳到SET,否则输出0
MOV DL,30H
MOV AH,2
INT 21H
DEC CX
JNZ ROT
RET
SET: MOV DL,31H
MOV AH,2
INT 21H
DEC CX
JNZ ROT
RET
PRINT ENDP
DETOHE PROC NEAR
;用该子程序来把一个十进制数转换成十六进制表示
REPEAT: LEA DX,BUF4
MOV AH,9
INT 21H
PUSH DS
SUB AX,AX
PUSH AX
CALL DECIBIN
CMP AL,1BH
JZ EXIT3
CALL CRLF
CALL BINIHEX
CALL CRLF
JMP REPEAT
EXIT3: RET
DETOHE ENDP
DECIBIN PROC NEAR
;输入一个五位的十进制数
MOV BX,0
MOV CX,0
NEWCHAR: CMP CX,5
JNB EXIT4
MOV AH,1
INT 21H
CMP AL,1BH
JZ EXIT4
SUB AL,30H
JL EXIT4
CMP AL,9
JG EXIT4
CBW
INC CX
XCHG AX,BX
MOV DX,10
MUL DX
XCHG AX,BX
ADD BX,AX
JMP NEWCHAR
EXIT4: RET
DECIBIN ENDP
BINIHEX PROC NEAR
;把BX中的十进制数转换成十六进制输出
MOV CH,4
ROTATE: MOV CL,4
ROL BX,CL
;把BX中高四位移到低四位,放到AL中
MOV AL,BL
AND AL,0FH
ADD AL,30H
CMP AL,3AH
;判断是否为数字
JL PRINTIT
ADD AL,7
PRINTIT: MOV DL,AL
MOV AH,2
INT 21H
DEC CH
JNZ ROTATE
RET
BINIHEX ENDP
BETOHE PROC NEAR
;用该子程序来把一个十六位二进制数转换成十六进制输出
START3: LEA DX,BUF5
MOV AH,9
INT 21H
PUSH DS
SUB AX,AX
PUSH AX
CALL INBIN
CMP AL,1BH
JZ EXIT5
CALL CRLF
CALL BINIHEX
CALL CRLF
JMP START3
EXIT5: RET
BETOHE ENDP
INBIN PROC NEAR
;输入十六二进制数
MOV BX,0
MOV CX,0
PUTIN:CMP CX,16
JNB EXIT6
MOV AH,1
INT 21H
CMP AL,1BH
JZ EXIT6
SUB AL,30H
JL EXIT6
CMP AL,1
JG EXIT6
CBW
INC CX
XCHG AX,BX
MOV DX,2
MUL DX
XCHG AX,BX
ADD BX,AX
JMP PUTIN
EXIT6: RET
INBIN ENDP
CODE ENDS
END START
