Search code examples
assemblyasciimasmx86-16

Masm 16bit converting Ascii to byte


I'm a beginner in assembly language and I have to find a solution fast.
The thing is I have to read a number from the person (3 digits), convert it to an integer and compare it to two values.
The problem is that after converting the comparisons are off, sometimes the result is correct sometimes it's not.

pile segment para stack 'pile'
    db 256 dup (0)
pile ends

data segment
ageper db 4,5 dup(0)
bigg db 13,10,"bigger than 146 ",13,10,"$"
lesss db 13,10,"less than 0 ",13,10,"$"
right db 13,10,"correct number 123 ",13,10,"$"
theint db 0


exacnumber db 123
data ends

code segment
main proc far

    assume cs:code
    assume ds:data
    assume ss:pile
    mov ax,data
    mov ds,ax

    mov ah,0ah
    lea dx,ageper
    int 21h

    mov ch,0
    cmp ageper[4],0
    jz phase2
    mov ah,ageper[4]
    sub ah,48
    add theint,ah
    phase2:
    mov cl,10
    cmp ageper[3],0
    jz phase3
    mov ah,ageper[3]
    sub ah,48
    mov al,ah
    mul cl
    add theint,al
    phase3:
    mov cl,100
    cmp ageper[2],0
    jz phase4
    mov ah,ageper[2]
    sub ah,48
    mov al,ah
    mul cl
    add theint,al

    phase4:
    cmp theint,123
    je yes
    cmp theint,130
    jg big
    cmp theint,0
    jl less
    jmp ending


    big:
    mov ah,09h
    lea dx,bigg
    int 21h
    jmp ending

    yes:
    mov ah,09h
    lea dx,right
    int 21h
    jmp ending

    less:
    mov ah,09h
    lea dx,lesss
    int 21h


    ending:
    mov ageper,20
    mov ageper[1],20

    mov ah,02
    lea dx,theint
    int 21h

    mov ah,4ch
    int 21h
main endp
code ends
    end main

Solution

  • cmp ageper[4],0
    jz phase2
    ...
    cmp ageper[3],0
    jz phase3
    ...
    cmp ageper[2],0
    jz phase4
    

    Your program performs erratically because you're not interpreting the input correctly!
    The simple 3-digit input recieved from DOS need not be checked for the number zero like you did. Just remove those 3 cmp's and jz's.


    Another small logical error is that when the number is bigger than 130, you report it as being bigger than 146.


    mov ageper,20
    mov ageper[1],20
    

    These instruction make no sense!


    mov ah,02
    lea dx,theint
    int 21h
    

    Here you're confused in the use of the correct DOS function. Function 02h uses the DL register, function 09h uses the DX register. Please look it up in your manual.


    To address the issue reported by @Michael (to deal with 3-digit numbers from 256 to 999), define the theint variable as word and add to it as shown below:

    theint dw 0
    
    mov ch, 0
    mov cl, ageper[4]
    sub cl, 48
    mov theint, cx       <<< Use MOV the first time!
    phase2:
    mov cl, 10
    mov al, ageper[3]
    sub al, 48
    mul cl
    add theint, ax       <<< Add AX in stead of AH
    phase3:
    mov cl, 100
    mov al, ageper[2]
    sub al, 48
    mul cl
    add theint, ax       <<< Add AX in stead of AH