DATAS SEGMENT
n EQU 16 ;n表示和的最大位数
m EQU n/2 ;因为和是ASCII码要转换成BCA码所以m=n/2
k EQU 9*m+6 ;BUF0至BUF5的字节总数
BUF0 DB 1 DUP (30H);30H为0的ASCII码
BUF1 DB n DUP(0) ;被加数(ASCII),n=8
DB 1 DUP (30H);30H为0的ASCII码
BUF2 DB n DUP(0) ;加数(ASCII)
BUF3 DB m DUP(0) ;被加数(BCD)
BUF4 DB m DUP(0) ;加数(BCD)
FHA DB 4 DUP(?) ;用于保存‘+’、‘-’、数据长度
SBC DB m DUP(?) ;BCD码形式的和
SAS DB n DUP(?) ;ASCII码形式的和
BUF5 DB 30H,n DUP(0),30H,n DUP(0),n DUP(0),4 DUP(?),m DUP(?),n DUP(?)
DATAS ENDS
STACKS SEGMENT
DB 100 DUP(?)
;此处输入堆栈段代码
STACKS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
INPT1 PROC
;输入被加数到BUF1按‘+’结束
LEA SI,BUF1
MOV CX,0 ;CX用来统计输入数的字长
IN1:MOV AH, 01H
INT 21H
CMP AL,'+'
JZ BJS1
CMP AL,'-'
JZ BJS1
MOV [SI],AL
INC SI
INC CL
JMP IN1
;将BUF1中的ASCII转换成BCD码到BUF3
BJS1:
MOV [FHA],AL
MOV 1[FHA],CL
LEA DI,BUF3
MOV BX,2
MOV AX,CX
DIV BL
ADD AL,AH
MOV CL,AL
AB1: DEC SI ;AB1--ASCII转换成BCD码
MOV AL,[SI]
SUB AL,30H
DEC SI
MOV AH,[SI]
SUB AH,30H
PUSH CX
MOV CL,4
SHL AH,CL
POP CX
ADD AL,AH
MOV [DI],AL
INC DI
LOOP AB1
;输入加数到BUF2按‘=’结束
LEA SI,BUF2
MOV CX,0 ;CX用来统计输入数的字长
IN2:MOV AH, 01H
INT 21H
CMP AL,'='
JZ JAS
MOV [SI],AL
INC SI
INC CX
JMP IN2
;将BUF2中的ASCII转换成BCD码到BUF4
JAS:
MOV 2[FHA],CL
LEA DI,BUF4
MOV BX,2
MOV AX,CX
DIV BL
ADD AL,AH
MOV CL,AL
AB2: DEC SI ;AB2--ASCII转换成BCD码
MOV AL,[SI]
SUB AL,30H
DEC SI
MOV AH,[SI]
SUB AH,30H
PUSH CX
MOV CL,4
SHL AH,CL
POP CX
ADD AL,AH
MOV [DI],AL
INC DI
LOOP AB2
RET
INPT1 ENDP
;加法子程序
JAF PROC
CLC
MOV CL,m ;m=8
LEA BX,BUF3
LEA SI,BUF4
LEA DI,SBC
ADC_:MOV AL,[BX]
ADC AL,[SI]
DAA
MOV [DI],AL
INC SI
INC DI
INC BX
LOOP ADC_
RET
JAF ENDP
;减法子程序
JIAF PROC
SBB_:MOV AL,1[FHA]
CMP AL,2[FHA]
JA BDJ1 ;被加数长度大于加数长度,即被加数大于加数
JZ BZJ1 ;被加数长度等于加数长度,进行大小比较
JMP BBJ ;被加数长度小于加数长度,即被加数小于加数
BZJ1:MOV CL,AL ;被加数长度等于加数长度,进行大小比较
LEA SI,BUF1
LEA DI,BUF2
BZJ3:MOV AL,[SI]
CMP AL,[DI]
JA BDJ1 ;被加数当前位大于加数当前位即被加数大于加数跳转
JB BBJ ;被加数当前位小于加数当前位即被加数小于加数跳转
INC SI ;被加数当前位等于加数当前位,调整指针继续比较
INC DI
LOOP BZJ3
JMP BDJ1 ;被加数等于加数
BBJ:MOV AH,02H
MOV DL,'-'
INT 21H
CLC
MOV CL,m
LEA BX,BUF4
LEA SI,BUF3
LEA DI,SBC
JMP BDJ
BDJ1:CLC
MOV CL,m
LEA BX,BUF3
LEA SI,BUF4
LEA DI,SBC
BDJ:MOV AL,[BX]
SBB AL,[SI]
DAS
MOV [DI],AL
INC SI
INC BX
INC DI
LOOP BDJ
RET
JIAF ENDP
;BCD码转ASCII码子程序
BCD_ASC PROC
MOV CX,m ;m=8
LEA SI,SBC
LEA DI,SAS
BC_as:MOV AL,[SI]
MOV AH,AL
AND AL,0FH
ADD AL,30H
MOV [DI],AL
INC DI
PUSH CX
MOV CX,4
SHR AH,CL
POP CX
ADD AH,30H
MOV [DI],AH
INC DI
INC SI
LOOP BC_as
MOV CL,n ;这里n等于16
DIS1:DEC DI ;把首位的0去掉 例如:0+1=00000001显示结果1
CMP BYTE PTR[DI],30H
JNZ DISP ;首位不为0跳转
LOOP DIS1
JNZ DISP ;CX不等于0 即结果不为0跳转
MOV DL,'0' ;CX等于0 即结果为0则显示0结束
MOV AH,02H
INT 21H
JMP DIS2
DISP:MOV DL,[DI]
MOV AH,02H
INT 21H
DEC DI
LOOP DISP
DIS2:RET
BCD_ASC ENDP
;数据段初始化子程序
CLC1 PROC
MOV CX,K
LEA SI,BUF5
LEA DI,BUF0
CLC2:MOV AL,[SI]
MOV [DI],AL
INC SI
INC DI
LOOP CLC2
RET
CLC1 ENDP
START:
;主程序:16位数以内整数加减法
MOV AX,DATAS
MOV DS,AX
;此处输入代码段代码
CALL INPT1 ;调用输入子程序
CMP [FHA],'+' ;判断加减号
JNZ Jiha ;是'-'跳转到减法
CALL JAF ;调用加法子程序
JMP B_A1 ;跳转到BCD 转ACSII子程序
Jiha:CALL JIAF ;调用减法子程序
B_A1:CALL BCD_ASC ;将和转换成十进制数保存在SAS中
MOV DL,0DH ;回车换行
MOV AH,02H
INT 21H
MOV DL,0AH
MOV AH,02H
INT 21H
CALL CLC1 ;调用数据段初始化子程序
JMP START ;重新输入
MOV AH,4CH
INT 21H
CODES ENDS
END START
|