Erfan Ahmadi
Erfan Ahmadi

Reputation: 123

PrimeCheck 8086 Assembly Bug

I wrote a 8086 Assembly program which does the following thing:

  1. Gets Input From User
  2. Convert it to integer
  3. Check if it is prime

The problem is with step 3 and it has a bug. It says 9 is a prime and is in an infinite loop when input is 2. I checked and there is no problem with input. I don't know what the problem is.

Code:

    MOV AL,NUM
    MOV BL,02H      ; The Dividing starts from 2, Hence BH is compare to 02H
    MOV DX,0000H    ; To avoid Divide overflow error
    MOV AH,00H      ; To avoid Divide overflow error

Loop to check for Prime No

L1:
    DIV BL
    CMP AH,00H      ; Remainder is compared with 00H (AH)
    JNE NEXT
    INC BH          ; BH is incremented if the Number is divisible by current value of BL
NEXT:
    CMP BH,02H      ; If BH > 02H, There is no need to proceed, It is not a Prime
    JE FALSE        ; The no is not a Prime No
    INC BL          ; Increment BL
    MOV AX,0000H    ; To avoid Divide overflow error
    MOV DX,0000H    ; To avoid Divide overflow error
    MOV AL,NUM      ; Move the Default no to AL
    CMP BL,NUM      ; Run the loop until BL matches Number. I.e, Run loop x no of times, where x is the Number given
    JNE L1          ; Jump to check again with incremented value of BL

Print Results:

    ;To display The given no is a Prime No
TRUE:
    LEA DX,MSG
    MOV AH,09H      ; Used to print a string
    INT 21H
    JMP EXIT

    ;To display The given no is not a Prime No
FALSE:    
    LEA DX,NMSG
    MOV AH,09H      ; Used to print a string
    INT 21H

I think it only happens for one digit numbers.

Upvotes: 1

Views: 362

Answers (1)

Fifoernik
Fifoernik

Reputation: 9899

CMP BH,02H
JE FALSE
;
CMP BL,NUM
JNE L1   

This is your problem.

If you don't allow dividing the number by itself then your false criterion should become CMP BH, 1.
If you do allow dividing the number by itself (but why should you?) checking for BH=2 is correct.


The number is not prime as soon as you get a zero remainder from division by 2 to N-1.
e.g. for the number 9, you divide by 2, 3, 4, 5, 6, 7, 8 The zero remainder already happens at 3 and thus 'not prime'

 MOV  BL, 2
L1:
 XOR  AX, AX
 MOV  AL, NUM
 DIV  BL
 TEST AH, AH
 JZ   FALSE
 INC  BL
 CMP  BL, NUM
 JB   L1    

is in an infinite loop when input is 2.

You must single out that case. You can't iterate from 2 to N-1 for the number 2.
The smallest number you can safely process is 3 (2 to 2).

The reason why your code crashes on this is because you've used JNE L1. See in my snippet how I've used JB L1?

Upvotes: 1

Related Questions