问题描述:
三角形判断。输入a,b,c 三边后,判断是否能构成三角形,如能构成三角形,输出三角形的周长,否则输出“ERROR”。要求:提示输入三角形三边长度a b c;键盘输入,中间空格隔开;Enter 键结束输入,并换行显示判断结果。
附加功能有:
1.判断输入是否符合规范(如字母不能出现,数与数之间只有一个空格隔开)若溢出则重新输入
2.判断最后的结果是否有溢出,若溢出则重新输入
C/C++20行之内能解决的代码,汇编硬是写了我两百多行,说多了都是泪,直接上代码(有大量注释):
;测试样例1:
;输入3 4 5
;输出12
;测试样例2:
;输入100 200 300
;输出ERROR
enterline macro ;定义回车换行的宏指令
mov dl,13
mov ah,2
int 21h
mov dl,10
mov ah,2
int 21h
endm
DATAS SEGMENT
;此处输入数据段代码
input db 'Please input the length of tiangle with three numbers,use a space between numbers:$'
output db 'ERROR$'
output1 db 'The circumference of this triangle is:$'
err db 'Illegal input! Please Try Again$'
out1 db 'Sorry, please leave the result between 0 and 65535.Please Try Again$'
buf db 20,?,20 dup(0) ;定义键盘接收字符缓冲区,最多接收19个字符
a dw ?
b dw ?
cc dw ? ;a b cc 分别是三条线段
flag db 0
DATAS ENDS
STACKS SEGMENT
;此处输入堆栈段代码
STACKS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
MOV AX,DATAS
MOV DS,AX
;此处输入代码段代码
begin:
lea dx,input ;给出输入提示
mov ah,9
int 21h
enterline ;回车换行
lea dx,buf ;从键盘接收输入数值放入buf缓冲区(输入操作)
mov ah,10
int 21h
enterline ;回车换行
mov cl,buf+1 ;获取实际键入字符数,置于CX寄存器中
xor ch,ch ;ch清0
xor di,di ;累加器清0
xor dx,dx ;dX寄存器清0
mov bx,1 ;由于从个位数开始算起,因而将所乘权值设为1
lea si,buf+2 ;将si指向接收到的第1个字符位置
add si,cx ;因为从个位算起,所以将si指向最后1个接收到的个位数
dec si ;往回减1使其指向字串最后一个元素
;cov是检测并生成第一个数字的步骤
cov:mov al,[si] ;取出个位数给al
cmp al,' '
jz next1 ;遇见空格则跳转
cmp al,'0' ;边界检查:如果输入不是0-9的数字,就报错
jb wrong
cmp al,'9'
ja wrong
sub al,30h ;将al中的ascii码转为数字
xor ah,ah
mul bx ;将当前位上的数值乘以当前位的权值
add di,ax ;将形成的数值叠加放在累加器di中
mov ax,bx ;将BX中的数位权值扩大10倍,此处需要借助ax来实现
mov bx,10
mul bx
mov bx,ax
dec si ;si指针减1,指向前一数位
loop cov ;按CX中的字符个数计数循环
;跳到次处表明第一个数字已经生成,接着去检测第二个数字
next1:
mov a,di
xor ax,ax
xor di,di ;累加器清0
xor bx,bx
mov bx,1 ;由于从个位数开始算起,因而将所乘权值设为1
dec si ;向前移动一格位置
dec cx ;遇到空格cx相应的减少1
;cov2是检测并生成第2个数字
cov2:
mov al,[si] ;取出个位数给al
cmp al,' '
jz next2 ;遇见空格则跳转
cmp al,'0' ;边界检查:如果输入不是0-9的数字,就报错
jb wrong
cmp al,'9'
ja wrong
sub al,30h ;将al中的ascii码转为数字
xor ah,ah
mul bx ;将当前位上的数值乘以当前位的权值
add di,ax ;将形成的数值放在累加器di中
mov ax,bx ;将BX中的数位权值扩大10倍,此处需要借助ax来实现
mov bx,10
mul bx
mov bx,ax
dec si ;si指针减1,指向前一数位
loop cov2 ;按CX中的字符个数计数循环
;跳到次处表明第2个数字已经生成,接着去检测第3个数字
next2:
mov b,di
xor ax,ax
xor di,di ;累加器清0
xor bx,bx
mov bx,1 ;由于从个位数开始算起,因而将所乘权值设为1
dec si
dec cx
;cov3是检测并生成第3个数字
cov3:mov al,[si] ;取出个位数给al
sub al,30h ;将al中的ascii码转为数字
xor ah,ah
mul bx ;将当前位上的数值乘以当前位的权值
add di,ax ;将形成的数值放在累加器di中
mov ax,bx ;将BX中的数位权值扩大10倍,此处需要借助ax来实现
mov bx,10
mul bx
mov bx,ax
dec si ;si指针减1,指向前一数位
loop cov3 ;按CX中的字符个数计数循环
next3:
mov cc,di
;三个数a b cc已经生成后,接下来开始进行定义的比较,如a+b 和cc去比较
mov bx,a
mov cx,b
add bx,cx
cmp bx,cc
jbe error ;若不满足两边之和大于第三边则跳error
mov bx,b
mov cx,cc
add bx,cx
cmp bx,a
jbe error
mov bx,a
mov cx,cc
add bx,cx
cmp bx,b
jbe error
;上述比较全部通过时代表能构成一个三角形
mov bx,a; ;下面是溢出判断操作
add bx,b;
jo yichu
add bx,cc;
jo yichu
;输出结果提示语
lea dx,output1 ;给出输入提示
mov ah,9
int 21h
enterline ;回车换行
;求三角形周长
xor ax,ax
mov ax,a
add ax,b
add ax,cc
;三角形周长储存在ax中,接下来转为字串并输出
xor dx,dx ;先清0
xor bx,bx
xor cx,cx
mov bx,10000 ;初始数位权值为10000
cov1:
xor dx,dx ;将dx:ax中的数值除以权值
div bx
mov cx,dx ;余数备份到CX寄存器中
cmp flag,0 ;检测是否曾遇到非0商值
jne nor1 ;如遇到过,则不管商是否为0都输出显示
cmp ax,0 ;如未遇到过,则检测商是否为0
je cont ;为0则不输出显示
nor1:
mov dl,al ;将商转换为ascii码输出显示
add dl,30h
mov ah,2
int 21h
mov flag,1 ;曾遇到非0商,则将标志置1
cont:
cmp bx,10 ;检测权值是否已经修改到十位了
je outer ;如果相等,则完成最后的个位数输出显示
xor dx,dx ;将bx数位权值除以10
mov ax,bx
mov bx,10
div bx
mov bx,ax
mov ax,cx ;将备份的余数送入AX
jmp cov1 ;继续循环
outer:
mov dl,cl ;最后的个位数变为ascii码输出显示
add dl,30h
mov ah,2
int 21h
enterline
jmp stop
error: ;输出"ERROR"
lea dx,output
mov ah,9
int 21h
wrong: ;给出相应的边界错误提示
lea dx,err
mov ah,9
int 21h
enterline
jmp begin ;如出错则返回起始点重新输入
yichu: ;溢出的提示
lea dx,out1
mov ah,9
int 21h
enterline
jmp begin ;返回起始点重新输入
stop:
MOV AH,4CH
INT 21H
CODES ENDS
END START
附上个人的另一个blog解释:
https://www.cnblogs.com/xwh-blogs/p/12544565.html