Search code examples
assemblyx86dos

Check if number is divisible by 2, if yes, print the number


Well, here is a piece of my ASM code:

    MOV AH, 0 ;reset AH before division
    MOV AL,[myNum] ;move the inputed number to AL
    DIV two ;div 123 / 2;
    CMP AH,0
    JNE inputIsPrime

    ;If 123 % 2 = 0, output 123 / 2.
    DIV ten
    MOV DH,AH

    SUB AL,'0'
    MOV AH,2
    MOV DL, AL
    INT 21h

    MOV divisionCalc,DH

    MOV AH,2
    MOV DL,DH
    INT 21h
    JMP endProg

What I'm trying to achieve here is, after I write "60" to keyboard and press enter, I get the wrong output. I want to get the number "30" because 60/2 = 30. If I enter 42, I want to get 21 as output.

Any ideas why my code fails?

Here's the full code:

.MODEL SMALL
.STACK 100h
.DATA

DisplayString DB 'Enter number up to 120:', 13,10,'$'
isPrimeNum DB 'is prime', 13,10,'$'
    goodMSG DB 'good', 13,10,'$'
        badMSG DB 'bad', 13,10,'$'
divisionCalc DB ?
myNum DB ?
two DB 2
three DB 3
five DB 5
seven DB 7
ten DB 10
eleven DB 11

    .CODE
Begin:
    MOV AX,@DATA
    MOV DS,AX

    MOV AH,9
    MOV DX,OFFSET DisplayString
    INT 21h

    MOV BL,0 ; Initialize BL to zero!

    ; //READ 3 DIGITS // ;
    ;read first digit for e.g. '1'
    MOV ah,1h
    INT 21h ;read into AL
    SUB AL,30h ; Convert the digit from ASCII to DECIMAL
    MOV myNum,AL

    MOV AH,1
    INT 21h

    CMP AL,13 ;is it Enter?
    JE endInput
    SUB AL,'0' ;Not enter, let's save this new char
    MOV CL, AL ; we save the 2nd char to CL
    MOV AL, myNum ; lets move our first char to AL
    MUL Ten ; multiply by 10 the first char
    MOV myNum,AL ;move that to myNum
    ADD myNum,CL ; add to AL the 2nd char.

    MOV AH,1
    INT 21h

    CMP AL,13 ; is it enter?
    JE endInput
    SUB AL,'0' ;Not enter, let's save this new char
    MOV CL, AL ; we save the 2nd char to CL
    MOV AL, myNum ; lets move our first char to AL
    MUL Ten ; multiply by 10 the first char
    MOV myNum,AL ;move that to myNum
    ADD myNum,CL ; add to AL the 2nd char.

    mov AH,1 ; if the number is 3 chars then this will be the enter now. 
    int 21h 

    ; // FINISH READING 3 DIGITS // ;
    endInput:

            ; AL = AX / two
        ; AH = AX % two
MOV AH, 0 ;reset AH before division
MOV AL,myNum ;move the inputed number to AL
DIV two ;div 123 / 2;
CMP AH,0
JNE inputIsPrime

;If 123 % 2 = 0, output 123 / 2.
DIV ten
MOV DH,AH

SUB AL,'0'
MOV AH,2
MOV DL, AL
INT 21h

MOV divisionCalc,DH

MOV AH,2
MOV DL,DH
INT 21h
JMP endProg

inputIsPrime:
MOV AH,9
MOV DX,OFFSET isPrimeNum
INT 21h

endProg:
MOV AH,4Ch
INT 21h
END Begin

Solution

  • the easiest way to divide by two, is to right shift the value for a single bit
    the bit shiftet will be stored in the carry flag

    so

    shr AX,1
    jnc isDividable    ; no carry set = there was no division "rest"
    

    will check if AX is divisable by 2