assemblydecimalx86-16emu8086triangle

Assembler that reads 3 decimal numbers L1,L2,L3 two digits mostly then indicate whether these numbers can represent the sides of a triangle


L2+L3>= L1 et L2+L1>= L3 et L1+L3>= L2 are the 3 conditions that must be verified to admit if it's a triangle or not. I tried the code below but it's giving me wrong answers and I'd like to know why.

    "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."

Solution

  • Quoting from my answer to your previous question:

    mov dl, offset msg
    

    This is an error that you should be aware of. The DOS.PrintString function 09h expects the address of the string in the word-sized DX register. You should not only load the low byte DL and trust the high byte DH to contain 0. So write mov dx, OFFSET msg.

    In today's program you have multiple instances (5) of the same error! Did you read that other answer? Please read https://stackoverflow.com/help/someone-answers to learn about what is expected from you after you received an answer. Thank you.

    Other problems

    You are storing the individual numbers in the BL, CL, and DH registers, but you have a typo for the third one:

    mov dh,al   ;l3 dans dh
    
    mov ah,01h
    int 21h
    sub al,48
    add dl,al
    

    Notice that you're erroneously adding to the DL register?


    Your condition proc (for which I had to improve the messed-up layout) shows another multiple instances (3) of something my previous answer already talked about!

    mov [som1],cl
    add [som1],dh
    cmp [som1],bl
    jae etq
    
    etq:
    inc si 
    

    The AboveOrEqual condition is the one that is fine and for which you will increment SI and continue the process. This means that you need to jump out based on the opposite condition. Presently, you just happily continue whether the comparison is good or bad. See next solution that does not use those som variables and that reports about success via the carry flag:

    ; IN () OUT (CF) L2+L3>= L1 et L2+L1>= L3 et L1+L3>= L2
    condition:
      mov  al, cl
      add  al, dh
      cmp  al, bl
      jb   etq
      mov  al, cl
      add  al, bl
      cmp  al, dh
      jb   etq
      mov  al, bl
      add  al, dh
      cmp  al, cl
    etq:
      ret                 ; CF=0 okay, CF=1 not okay
    

    cmp si,3      
    je fin 
    jne fin
    

    Together je and jne cover every possible outcome from the cmp. You will always jump to fin where you display "triangle valide".
    See how easy it can be and pay attention to how I changed condition to report through the carry flag (instead of counting in the SI register):

      call condition          ; -> CF
      mov  dx, offset res1    ; "triangle invalide"
      jc   fin
      mov  dx, offset res2    ; "triangle valide"
    fin:
      mov  ah, 09h
      int  21h