so this is my first time writing a post here. I'm very new to Assembly Language and started the learning journey with EMU8086. Recently I wrote a program that detects if the number entered is either positive or negative and determines whether it's a prime number or not. I made it the first part (detecting positive or negative numbers, using array) but for some reason it keeps saying "Not a prime number" for any numbers I enter. I tried to get it to copy the number stored in the array and bring it over to the prime/not prime section of the program but to not avail. Anyone know what exactly the problem is? I'm pretty lost right now :/
Here's the code I wrote:
.MODEL SMALL
.STACK 100H
.DATA
ARRAY DB DUP('$')
NUM DB ?
MSG1 DB 0AH,0DH,'ENTER YOUR DESIRED NUMBER:','$'
MSG2 DB 0AH,0DH,'NOT A PRIME NUMBER','$'
MSG3 DB 0AH,0DH,'A PRIME NUMBER','$'
POSI DB 0AH,0DH,'A POSITIVE NUMBER','$'
NEGA DB 0AH,0DH,'A NEGATIVE NUMBER','$'
.CODE
MAIN PROC
MOV AX,@DATA
MOV DS,AX
MOV SI, OFFSET ARRAY
LEA DX,MSG1
MOV AH,9
INT 21H
MOV AH,1
INT 21H
CMP AL,13
JE CHECK
MOV [SI],AL
INC SI
JMP L1
L1:
MOV AH,1
INT 21H
CMP AL,13
JE CHECK
MOV [SI],AL
INC SI
JMP L1
CHECK:
CMP ARRAY, '-' ;IF ARRAY CONTAINS - SIGN THEN THE NUMBER IS NEGATIVE
JE L2
MOV DX, OFFSET POSI
MOV AH,9
INT 21H
JMP EXIT1
L2:
MOV DX, OFFSET NEGA
MOV AH,9
INT 21H
EXIT1:
mov al, [NUM]
mov bl, al
sub al, 2
mov cl, al ; counter value
; original input
mov dl, 2
l3:
mov ax, bx
div dl
cmp ah, 0h
jz pnot
inc dl
loop l3
mov ah, 9h
lea dx, msg3
int 21h
jmp end
pnot:
mov ah, 9h
lea dx, msg2
int 21h
END:
MOV AH,4CH
INT 21H
MAIN ENDP
END MAIN
Any help would be greatly appreciated, thank you in advance!
CodePudding user response:
You are adding your new code that wants to deal with prime numbers to an already broken program!
In the .DATA
section you have written:
ARRAY DB DUP('$') NUM DB ?
It's beyond me how this gets through emu8086's parser seeing the absence of a count for the DUP
operator. Probably both ARRAY and NUM refer to the same memory address where there is room reserved for just 1 byte.
Your "positive/negative" program inputs a multi-digit number with an optional minus in front of it, and that program seemed to work fine since you were only comparing a single byte to "-" and having the first message been overwritten didn't show itself.
The program that you write today is not dealing with a multi-digit number, but rather just processes the first digit that was inputted (hopefully it was indeed a digit and not a minus character or anything else).
Because of the error with the definition of the ARRAY, the mov al, [NUM]
instruction can retrieve that first digit but this digit is still in its character form. It is an ASCII code in the range 48 to 57. You need to subtract 48 before you use it in your calculations.
The calculation is also dangerously wrong because you divide AX by DL without knowing what is in AH, and because you use the loop
instruction that depends on the CX register without knowing what is in CH.
Next code shows the corrections. I made no attempt at optimizing because that would hardly pay in this case... Anyway there's always Checking Prime number in 8086 Assembly for those interested in an optimized version of the code.
...
.DATA
ARRAY DB 16 DUP(0)
NUM DB 0
MSG1 DB 0AH,0DH,'ENTER YOUR DESIRED NUMBER:','$'
...
If you find that the first byte at ARRAY is '-'
then better not start the prime test
...
EXIT1: mov al, [ARRAY] ; ["0","9"]
sub al, 48 ; [0,9]
mov bl, al ;
mov bh, 0 ; AL -> BX (original number)
mov cl, al
mov ch, 0
sub cx, 2 ; AL-2 -> CX (loop count)
jbe YES ; Consider [0,2] prime for simplicity!
mov dl, 2 ; Processing [3,9] with CX=[1,7] so LOOP doesn't fail
l3: mov ax, bx
div dl
cmp ah, 0
je NO
inc dl
loop l3
YES: mov ah, 9h
lea dx, msg3
int 21h
jmp end
NO: mov ah, 9h
lea dx, msg2
int 21h
END: mov ax, 4C00h
int 21h
...