读取两位十进制数判断三角形合法性的汇编代码出错,求问题原因
汇编三角形判断程序错误排查
需求是编写汇编程序,读取三个以两位为主的十进制数L1、L2、L3,判断它们能否构成三角形(构成条件为:L2+L3≥L1、L2+L1≥L3、L1+L3≥L2)。以下是我编写的代码,但运行后输出结果错误,请帮忙排查问题:
data segment ; add your data here! msg1 db "entrez L1: $" msg2 db "entrez L2: $" msg3 db "entrez L3: $" res1 db "triangle invalide$" res2 db "triangle valide$" som1 db 255 som2 db 255 som3 db 255 ends stack segment dw 128 dup(0) ends code segment ;l1 bl ;l2 cl ;l3 dh condition proc near mov [som1],cl add [som1],dh cmp [som1],bl jae etq etq: inc si mov [som2],cl add [som2],bl cmp [som2],dh jae etq1 etq1: inc si mov [som3],bl add [som3],dh cmp [som3],cl jae etq2 etq2: inc si ret start: ; set segment registers: mov ax, data mov ds, ax mov es, ax mov si,0 mov ah,09h mov dl,offset msg1 int 21h mov ah,01h int 21h sub al,48 mov bl,10d mul bl mov bl,al ;l1 dans bl mov ah,01h int 21h sub al,48 add bl,al mov ah,02h mov dl,0Dh int 21h mov dl,0Ah int 21h mov ah,09h mov dl,offset msg2 int 21h mov ah,01h int 21h sub al,48 mov cl,10 mul cl mov cl,al ;l2 dans cl mov ah,01h int 21h sub al,48 add cl,al mov ah,02h mov dl,0Dh int 21h mov dl,0Ah int 21h mov ah,09h mov dl,offset msg3 int 21h mov ah,01h int 21h sub al,48 mov dh,10 mul dh mov dh,al ;l3 dans dh mov ah,01h int 21h sub al,48 add dl,al mov ah,02h mov dl,0Dh int 21h mov dl,0Ah int 21h call condition cmp si,3 je fin jne fin mov ah,09h mov dl,offset res1 int 21h jmp endd fin: mov ah,09h mov dl,offset res2 int 21h endd: mov ax, 4c00h ; exit to operating system. int 21h ends end start ; set entry point and stop the assembler.
错误点分析及修正
1. L3输入存储错误
读取L3的第二个数字时,代码写成add dl, al,但L3的十位已存在dh中,正确操作应该是将个位加到dh里,即add dh, al。这个错误会导致L3的数值完全错误,后续判断失去意义。
2. 条件判断逻辑错误(condition过程)
当前condition过程中,不管两边之和是否≥第三边,都会执行inc si。比如第一个判断:
cmp [som1],bl jae etq etq: inc si
无论som1 >= bl是否成立,都会走到etq执行inc si,最终si一定会被加到3,导致后续判断永远认为三个条件都满足。
正确逻辑应为:如果条件不满足,直接返回,不继续后续判断;只有条件满足时,才递增si并继续下一个判断。修改后的condition过程示例:
condition proc near ; 判断L2+L3 >= L1 mov al, cl add al, dh cmp al, bl jb invalid ; 不满足则跳转到invalid返回 inc si ; 判断L2+L1 >= L3 mov al, cl add al, bl cmp al, dh jb invalid inc si ; 判断L1+L3 >= L2 mov al, bl add al, dh cmp al, cl jb invalid inc si ret invalid: ret
这里直接用寄存器al计算和,避免不必要的内存操作,同时条件不满足时直接返回,保证si的数值准确反映满足的条件数量。
3. 主程序结果判断逻辑错误
主程序中:
cmp si,3 je fin jne fin
这行代码不管si是否等于3,都会跳转到fin,导致永远输出"triangle valide"(有效三角形)。正确写法应为:
cmp si,3 je fin ; 三个条件都满足,跳去输出有效 ; 否则执行输出无效的代码 mov ah,09h mov dl,offset res1 int 21h jmp endd fin: mov ah,09h mov dl,offset res2 int 21h
4. 内存变量som1/som2/som3的冗余使用
原代码中用som1等内存变量存储两边之和,完全可以用寄存器(比如al)直接计算,既提高效率,也避免内存访问可能带来的错误。
内容的提问来源于stack exchange,提问作者Zahra
相关产品推荐
相关产品推荐

