一、题目要求
键盘输入两个任意长度的十进制数(20位以内)的求和,用“-”来标识负数,正数可以不加符号或加“+”号。
(所用汇编语言编程环境:Masm for Windows 集成实验环境 2012.5)
二、题目分析
本题目要求实现任意长度的十进制数加法,相较于汇编指令的加法而言,该题的加法位数多且位数以及正负不确定,并且需要考虑的进位情况较为复杂。因此基于以上分析,使用传统的汇编指令加减法可能无法达到该题目的要求,需要结合存储器等资源来实现题目要求。
三、思路及流程图
鉴于题目要求的加减法数据位数过长,因此决定一位一位从内存中读取数据至寄存器进行加减并且记录是否进位或借位。首先在接收到输入数据时判断两个数据的位数是否相同,相同则将其ASCII码值减去30H并且存储,不相同则在位数较小的数据前面补零。然后进行符号的判断,若同号则将两个数据的绝对值相加并且获取符号,若不同号则将两个数据的绝对值相减并且获取符号。
四、程序代码
DATAS SEGMENT
;此处输入数据段代码
BUF1 DB 30
DB ?
DB 30 DUP('#')
DB '$'
BUF2 DB 30
DB ?
DB 30 DUP('#')
DB '$'
BUF3 DB 30 DUP(?),'$'
BUF4 DB 30 DUP(?),'$'
BUF0 DB 30 DUP('$'),'$'
message1 DB 'Please input the first number:','$'
message2 DB 0AH,0DH,'Please input the second number:','$'
message0 DB 0AH,0DH,'Result:','$'
message_fu DB '-','$'
message_zheng DB '+','$'
DATAS ENDS
STACKS SEGMENT
;此处输入堆栈段代码
DB 256 DUP(?)
STACKS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
MOV AX,DATAS
MOV DS,AX
;此处输入代码段代码
;输入加数1
LEA DX,message1
MOV AH,09H
INT 21H
LEA DX,BUF1
MOV AH,0AH
INT 21H
;输入加数2
LEA DX,message2
MOV AH,09H
INT 21H
LEA DX,BUF2
MOV AH,0AH
INT 21H
;处理加数
LEA SI,BUF1
INC SI
MOV AL,[SI]
LEA DI,BUF2
INC DI
MOV AH,[DI]
.IF AH>AL
MOV BH,AH
MOV BL,AL
SUB AH,AL
MOV CH,0
MOV CL,AH
LEA SI,BUF1
INC SI
INC SI
INC SI
LEA DI,BUF3
AGAIN1: MOV AL,0
MOV [DI],AL
INC DI
LOOP AGAIN1
MOV CH,0
MOV CL,BL
DEC CL
AGAIN2: MOV AL,[SI]
SUB AL,30H
MOV [DI],AL
INC SI
INC DI
LOOP AGAIN2
LEA SI,BUF2
INC SI
INC SI
INC SI
LEA DI,BUF4
MOV CH,0
MOV CL,BH
DEC CL
AGAIN3: MOV AL,[SI]
SUB AL,30H
MOV [DI],AL
INC SI
INC DI
LOOP AGAIN3
.ELSEIF AH<AL
MOV BL,AH
MOV BH,AL
SUB AL,AH
MOV CH,0
MOV CL,AL
LEA SI,BUF2
INC SI
INC SI
INC SI
LEA DI,BUF4
AGAIN4: MOV AL,0
MOV [DI],AL
INC DI
LOOP AGAIN4
MOV CH,0
MOV CL,BL
DEC CL
AGAIN5: MOV AL,[SI]
SUB AL,30H
MOV [DI],AL
INC SI
INC DI
LOOP AGAIN5
LEA SI,BUF1
INC SI
INC SI
INC SI
LEA DI,BUF3
MOV CH,0
MOV CL,BH
DEC CL
AGAIN6: MOV AL,[SI]
SUB AL,30H
MOV [DI],AL
INC SI
INC DI
LOOP AGAIN6
.ELSE
MOV BL,AL
MOV BH,AH
LEA SI,BUF1
INC SI
INC SI
INC SI
LEA DI,BUF3
MOV CH,0
MOV CL,AL
DEC CL
AGAIN55: MOV AL,[SI]
SUB AL,30H
MOV [DI],AL
INC SI
INC DI
LOOP AGAIN55
LEA SI,BUF2
INC SI
INC SI
INC SI
LEA DI,BUF4
MOV CH,0
MOV CL,AH
DEC CL
AGAIN66: MOV AL,[SI]
SUB AL,30H
MOV [DI],AL
INC SI
INC DI
LOOP AGAIN66
.ENDIF
;开始加减法
LEA SI,BUF1
LEA DI,BUF2
INC SI
INC SI
INC DI
INC DI
MOV AL,[SI]
MOV AH,[DI]
.IF AH == AL
DEC BH
MOV CH,0
MOV CL,BH
LEA SI,BUF3
LEA DI,BUF4
LEA BP,BUF0
AGAIN7: INC SI
INC DI
INC BP
LOOP AGAIN7
DEC SI
DEC DI
DEC BP
MOV AX,0
MOV BL,0
MOV CH,0
MOV CL,BH
AGAIN8: MOV AL,[SI]
MOV AH,[DI]
ADD AL,AH
.IF BL>0
ADD AL,BL
MOV BL,0
.ENDIF
.IF AL > 9
MOV BL,1
SUB AL,10
.ENDIF
MOV [BP],AL
DEC BP
DEC SI
DEC DI
LOOP AGAIN8
MOV CL,BH
ADD CL,1
LEA SI,BUF0
AGAIN9: MOV AL,[SI]
.IF AL != '$'
ADD AL,30H
MOV [SI],AL
.ELSE
MOV AH,'$'
MOV [SI],AH
.ENDIF
INC SI
LOOP AGAIN9
LEA DX,message0
MOV AH,09H
INT 21H
LEA SI,BUF1
INC SI
INC SI
MOV AL,[SI]
.IF AL=='-'
LEA DX,message_fu
MOV AH,09H
INT 21H
.ELSE
LEA DX,message_zheng
MOV AH,09H
INT 21H
.ENDIF
LEA DX,BUF0
MOV AH,09H
INT 21H
.ELSE
DEC BH
MOV CH,0
MOV CL,BH
LEA SI,BUF3
LEA DI,BUF4
LEA BP,BUF0
AGAIN71: INC SI
INC DI
INC BP
LOOP AGAIN71
DEC SI
DEC DI
DEC BP
MOV AX,0
MOV BL,0
MOV CH,0
MOV CL,BH
AGAIN81: MOV AL,[SI]
MOV AH,[DI]
.IF AL>AH
SUB AL,AH
SUB AL,BL
.ELSEIF AL==AH
SUB AL,AH
.ELSE
ADD AL,10
SUB AL,AH
MOV BL,1
.ENDIF
MOV [BP],AL
DEC BP
DEC SI
DEC DI
LOOP AGAIN81
MOV CL,BH
ADD CL,1
LEA SI,BUF0
AGAIN91: MOV AL,[SI]
.IF AL != '$'
ADD AL,30H
MOV [SI],AL
.ELSE
MOV AH,'$'
MOV [SI],AH
.ENDIF
INC SI
LOOP AGAIN91
LEA DX,message0
MOV AH,09H
INT 21H
LEA SI,BUF1
INC SI
INC SI
MOV AL,[SI]
.IF AL=='+'
LEA DX,message_zheng
MOV AH,09H
INT 21H
.ELSE
LEA DX,message_fu
MOV AH,09H
INT 21H
.ENDIF
LEA DX,BUF0
MOV AH,09H
INT 21H
.ENDIF
MOV AH,4CH
INT 21H
CODES ENDS
END START
五、测试结果
测试用例:11111111111111111111+22222222222222222222(20位数加法)
测试结果:
测试用例:-22222222222222222222-11111111111111111111(20位同号数减法)
测试结果:
测试用例:+22222222222222222222-11111111111111111111(20位异号数减法)
测试结果:
测试用例:+123456789-12345678(9位数减8位数)
测试结果:
测试用例:+12345678+111(8位数加3位数)
测试结果:
通过检验,以上结果均正确。
六、总结
本题由于加减法位数过多且不统一,采用了先通过补零统一位数,再从存储器中逐位取数至寄存器相加减并且记录进位借位,最后判断符号。通过对程序的测试可知代码较为完整的达到了题目的要求。