Tanay Chawda
Tanay Chawda

Reputation: 13

Checking Prime number in 8086 Assembly

I am trying to check if a given number is prime or not in 8086 Assembly program using Turbo Assembler. But maybe there is something wrong in my code, for some of the prime numbers(19,23,31,37) its showing its not a prime number. Rest of the prime numbers(2,3,5,7,11,17,29,41,...,71) are working well.

Here's the whole code:

DATA SEGMENT
NUM DB 37H
PR DB 0H
NPR DB 0H
DATA ENDS

CODE SEGMENT
START: ASSUME CS:CODE, DS:DATA
MOV AX, DATA
MOV DS, AX
MOV AL, NUM
MOV BL, 02H
MOV BH,00H
MOV DX,0000H
MOV AH,00H

UP:DIV BL 
CMP AH,00H
JNE NEXT
INC BH
NEXT: CMP BH, 02H
JE NPRIME
INC BL
MOV AX, 0000H
MOV DX, 0000H
MOV AL, NUM
CMP BL, NUM
JBE UP

PRIME: 
INC PR
JMP EXIT

NPRIME: 
INC NPR

EXIT:
MOV AH, 4CH
INT 21H

CODE ENDS
END START

Maybe the problem must be in this part?

UP:DIV BL 
CMP AH,00H
JNE NEXT
INC BH
NEXT: CMP BH, 02H
JE NPRIME
INC BL
MOV AX, 0000H
MOV DX, 0000H
MOV AL, NUM
CMP BL, NUM
JBE UP

Please let me know where I am going wrong, Thanks in advance!

Upvotes: 1

Views: 10736

Answers (1)

Sep Roland
Sep Roland

Reputation: 39306

I have tried your program and it works fine except that you seem to consider 0 and 1 prime numbers. That's not correct.

A prime number is a number bigger than 1, that is only divisible by itself and by 1.

The quick fix is below:

...
MOV AL, NUM
cmp al, 2           <<<< Add this line
jb  NPRIME          <<<< Add this line
MOV BL, 02H
MOV BH,00H
MOV DX,0000H
MOV AH,00H

UP:DIV BL 
CMP AH,00H
JNE NEXT
INC BH
NEXT: CMP BH, 02H
JE NPRIME
INC BL
MOV AX, 0000H
MOV DX, 0000H
MOV AL, NUM
CMP BL, NUM
JBE UP

PRIME: 
INC PR
JMP EXIT

NPRIME: 
INC NPR

EXIT:
...

Not much of an answer if I would leave it at that! So allow me the following observations:

  • Zeroing DX is a twice repeated, redundant operation
  • You can load BH and BL in one operation
  • Don't load the number at two different places
  • The variables PR and NPR are mutually exclusive, so a single variable would be enough
  • You don't need branching in order to increment the counter

The better fix is below:

  ...
  cmp  NUM, 2
  jb   NPRIME    ; 0 and 1 are no prime numbers
  mov  bx, 0002h ; BH=0 (counter), BL=2 (divisor)
UP:
  mov  al, NUM
  mov  ah, 0
  div  bl
  cmp  ah, 1     ; Only sets carry flag is remainder is 0
  adc  bh, 0     ; Conditional increment of counter
  cmp  bh, 2
  je   NPRIME
  inc  bl
  cmp  bl, NUM
  jbe  UP
PRIME: 
  inc  PR
NPRIME: 
EXIT:
...

Because your algorithm tries every divisor up to the number itself, even the above proposed changes will not make the program truly efficient.
I could add a version of the code that would be at least 10 times faster. In case you're interested, leave me a comment and perhaps I could add it in the weekend...

[edit]

A fast check for primality

Trying to reduce the number of iterations and especially the number of divisions (div is a costly operation) is what we're after here:

  • It is most efficient to split off the small numbers [0,3] first. This avoids extra tests in the loop.
  • Next we split off the even numbers because, except for the number 2 (that we already have split off), no even number is prime.
  • Therefore the loop only has to divide odd numbers. We can omit all the even divisors at once because dividing an odd number by an even number will never produce a zero remainder.
  • We only need to test divisors up to the integer square root of the number. Luckily we don't need to calculate it. As long as the quotient from the division is still greater than the divisor we have not yet reached the integer square root.
; IN (dl) OUT (cx) MOD (ax,bl)
TestPrime:
  xor  cx, cx         ; CX=0 means NotPrime
  cmp  dl, 4
  jb   .Less4
  mov  bl, 1
  test dl, bl
  jz   .No            ; Number is EVEN, so not prime
  ; Remaining candidates {5,7,9,11,13,15,...}
.Loop:
  add  bl, 2          ; Division by {3,5,7,9,11,....}
  mov  al, dl
  mov  ah, 0          ; Will divide AX by BL
  div  bl
  test ah, ah         ; Remainder == 0 ?
  jz   .No            ; Yes, found an additional divisor, so not prime
  cmp  al, bl         ; Quotient > divisor ?
  ja   .Loop          ; Yes, continue up to isqrt(number)
.Yes:
  inc  cx             ; CX=1 means Prime
  ret
.Less4:
  cmp  dl, 2
  jae  .Yes           ; 2 and 3 are prime, 0 and 1 are not prime
.No:
  ret

Prime numbers smaller than 256

Next table shows the number of DIV instructions that got executed and the time it took in nanoseconds. The middle columns are for the question's improved code, and the columns on the right are for today's optimized code. As numbers grow, so does the benefit.

Number IsPrime DIV's nsec DIV's nsec
251 1 250 4163 8 495
241 1 240 4140 8 428
239 1 238 3967 7 285
233 1 232 3869 7 263
229 1 228 3809 7 285
227 1 226 3779 7 255
223 1 222 3697 7 263
211 1 210 3494 7 255
199 1 198 3298 7 263
197 1 196 3276 7 263
193 1 192 3298 7 263
191 1 190 3186 7 263
181 1 180 3020 6 315
179 1 178 2990 6 308
173 1 172 2900 6 285
167 1 166 2802 6 232
163 1 162 2742 6 232
157 1 156 2667 6 240
151 1 150 2637 6 240
149 1 148 2524 6 240
139 1 138 2382 6 240
137 1 136 2352 6 240
131 1 130 2254 5 285
127 1 126 2171 5 293
113 1 112 1946 5 255
109 1 108 1893 5 225
107 1 106 1871 5 225
103 1 102 1848 5 210
101 1 100 1750 5 225
97 1 96 1713 5 225
89 1 88 1555 4 270
83 1 82 1457 4 270
79 1 78 1465 4 240
73 1 72 1390 4 195
71 1 70 1284 4 202
67 1 66 1202 4 210
61 1 60 1209 4 195
59 1 58 1082 4 195
53 1 52 976 3 255
47 1 46 871 3 263
43 1 42 804 3 180
41 1 40 773 3 187
37 1 36 728 3 172
31 1 30 616 3 180
29 1 28 601 2 225
23 1 22 510 2 232
19 1 18 435 2 172
17 1 16 413 2 172
13 1 12 360 2 172
11 1 10 315 1 217
7 1 6 247 1 142
5 1 4 217 1 150
3 1 2 187 0 165
2 1 1 172 0 165

Non prime numbers smaller than 256

Next table shows the number of DIV instructions that got executed and the time it took in nanoseconds. The middle columns are for the question's improved code, and the columns on the right are for today's optimized code. As numbers grow, so does the benefit.

Number IsPrime DIV's nsec DIV's nsec
255 0 4 270 1 195
254 0 126 2261 0 202
253 0 22 518 5 345
252 0 2 202 0 180
250 0 4 285 0 142
249 0 82 1532 1 217
248 0 3 240 0 150
247 0 18 510 6 345
246 0 2 210 0 165
245 0 6 270 2 232
244 0 3 255 0 165
243 0 8 338 1 217
242 0 10 375 0 180
240 0 2 217 0 157
238 0 6 360 0 142
237 0 78 1442 1 187
236 0 3 240 0 142
235 0 46 916 2 232
234 0 2 210 0 157
232 0 3 180 0 157
231 0 6 270 1 187
230 0 4 247 0 142
228 0 2 210 0 150
226 0 112 2066 0 142
225 0 4 247 1 195
224 0 3 240 0 142
222 0 2 217 0 150
221 0 16 435 6 338
220 0 3 240 0 150
219 0 72 1352 1 225
218 0 108 1931 0 142
217 0 30 646 3 278
216 0 2 210 0 157
215 0 42 924 2 232
214 0 106 1893 0 165
213 0 70 1322 1 217
212 0 3 240 0 157
210 0 2 165 0 150
209 0 18 488 5 323
208 0 3 270 0 165
207 0 8 255 1 217
206 0 102 1893 0 165
205 0 40 811 2 202
204 0 2 210 0 165
203 0 28 631 3 278
202 0 100 1795 0 165
201 0 66 1254 1 217
200 0 3 240 0 165
198 0 2 165 0 150
196 0 3 232 0 142
195 0 4 240 1 187
194 0 96 1750 0 142
192 0 2 165 0 150
190 0 4 315 0 142
189 0 6 270 1 195
188 0 3 255 0 142
187 0 16 428 5 308
186 0 2 202 0 142
185 0 36 804 2 232
184 0 3 240 0 165
183 0 60 1142 1 225
182 0 6 270 0 157
180 0 2 165 0 157
178 0 88 1720 0 142
177 0 58 1134 1 187
176 0 3 240 0 150
175 0 6 270 2 232
174 0 2 210 0 180
172 0 3 240 0 157
171 0 8 300 1 187
170 0 4 247 0 150
169 0 168 2938 6 345
168 0 2 210 0 165
166 0 82 1540 0 142
165 0 4 240 1 240
164 0 3 232 0 150
162 0 2 157 0 150
161 0 22 510 3 278
160 0 3 247 0 157
159 0 52 1014 1 187
158 0 78 1442 0 142
156 0 2 165 0 142
155 0 30 646 2 263
154 0 6 270 0 150
153 0 8 375 1 187
152 0 3 247 0 157
150 0 2 210 0 150
148 0 3 270 0 150
147 0 6 270 1 202
146 0 72 1352 0 150
145 0 28 631 2 232
144 0 2 202 0 157
143 0 12 390 5 308
142 0 70 1375 0 165
141 0 46 916 1 225
140 0 3 240 0 165
138 0 2 165 0 195
136 0 3 232 0 150
135 0 4 247 1 195
134 0 66 1247 0 142
133 0 18 488 3 308
132 0 2 165 0 172
130 0 4 247 0 187
129 0 42 879 1 195
128 0 3 240 0 165
126 0 2 165 0 142
125 0 24 556 2 263
124 0 3 240 0 165
123 0 40 811 1 150
122 0 60 1209 0 142
121 0 120 2134 5 308
120 0 2 210 0 142
119 0 16 473 3 278
118 0 58 1127 0 165
117 0 8 300 1 202
116 0 3 247 0 172
115 0 22 556 2 270
114 0 2 210 0 165
112 0 3 240 0 150
111 0 36 758 1 187
110 0 4 240 0 157
108 0 2 165 0 150
106 0 52 1097 0 150
105 0 4 240 1 202
104 0 3 240 0 150
102 0 2 165 0 142
100 0 3 232 0 157
99 0 8 300 1 165
98 0 6 270 0 165
96 0 2 165 0 142
95 0 18 488 2 217
94 0 46 1036 0 150
93 0 30 646 1 195
92 0 3 240 0 157
91 0 12 390 3 308
90 0 2 210 0 180
88 0 3 232 0 187
87 0 28 631 1 187
86 0 42 871 0 142
85 0 16 428 2 232
84 0 2 210 0 180
82 0 40 819 0 157
81 0 8 293 1 202
80 0 3 232 0 142
78 0 2 210 0 157
77 0 10 323 3 278
76 0 3 232 0 142
75 0 4 240 1 150
74 0 36 758 0 150
72 0 2 165 0 142
70 0 4 315 0 142
69 0 22 518 1 187
68 0 3 240 0 142
66 0 2 165 0 142
65 0 12 390 2 232
64 0 3 240 0 142
63 0 6 270 1 150
62 0 30 646 0 150
60 0 2 165 0 150
58 0 28 751 0 142
57 0 18 488 1 195
56 0 3 270 0 165
55 0 10 368 2 232
54 0 2 202 0 180
52 0 3 240 0 157
51 0 16 428 1 195
50 0 4 240 0 142
49 0 48 1044 3 270
48 0 2 210 0 165
46 0 22 593 0 157
45 0 4 240 1 187
44 0 3 240 0 165
42 0 2 202 0 142
40 0 3 270 0 142
39 0 12 398 1 187
38 0 18 488 0 142
36 0 2 210 0 150
35 0 6 270 2 247
34 0 16 420 0 150
33 0 10 323 1 187
32 0 3 232 0 142
30 0 2 202 0 150
28 0 3 263 0 165
27 0 8 293 1 195
26 0 12 465 0 142
25 0 24 563 2 232
24 0 2 210 0 142
22 0 10 323 0 150
21 0 6 270 1 202
20 0 3 232 0 150
18 0 2 225 0 150
16 0 3 232 0 157
15 0 4 232 1 187
14 0 6 263 0 142
12 0 2 217 0 157
10 0 4 315 0 157
9 0 8 308 1 217
8 0 3 247 0 150
6 0 2 217 0 142
4 0 3 240 0 165
1 0 0 165 0 187
0 0 0 157 0 187

Upvotes: 3

Related Questions