I have written an assembly program where my goal is to print out prime numbers the amount of times that the user enters. The user only has to enter one number, say, 15, and the first 15 prime numbers will be printed. The range the user can enter in is between 1 and 200.
My error-catching works, so entering anything below 1 or above 200 re-prompts for another number, but when I enter a number in the correct range that is supposed to be valid, nothing is printed out and the program pretty much stops in its tracks, but does not end. Any help would be greatly appreciated, here is the code I have as of right now.
INCLUDE Irvine32.inc
; Constant definitions
LOWER_BOUND = 1
UPPER_BOUND = 200
.data
; All text prompts and statements
nameAndProgram BYTE "Prime Numbers Programmed by Norman O'Brien", 13, 10, 0
promptPt1 BYTE "Enter the number of prime numbers you would like to see.", 13, 10, 0
promptPt2 BYTE "I'll accept orders for up to 200 primes.", 13, 10, 0
enterNumberOf BYTE "Enter the number of primes to display [1 ... 200]: ", 0
outOfRange BYTE "No primes for you! Number out of range. Try again.", 13, 10, 0
certified BYTE "Results certified by Norman O'Brien. Goodbye.", 13, 10, 0
spacer BYTE " ", 0 ; This is for separating the prime numbers when it is printed
; Variables
validNum DWORD 0
userInput SDWORD ?
.code
main PROC
call introduction
call getUserData
call showPrimes
call farewell
Invoke ExitProcess,0 ; exit to operating system
main ENDP
introduction PROC
; Print the my name and program name
MOV EDX, OFFSET nameAndProgram
call WriteString
call CrLf
; Print first part of prompt info
MOV EDX, OFFSET promptPt1
call WriteString
; Print second part of prompt info
MOV EDX, OFFSET promptPt2
call WriteString
call CrLf
ret
introduction ENDP
getUserData PROC
top:
MOV EDX, OFFSET enterNumberOf
call WriteString
call ReadInt
MOV userInput, EAX
call validate
MOV EAX, validNum
CMP EAX, 0
JE top
ret
getUserData ENDP
validate PROC
MOV EBX, userInput
CMP EBX, LOWER_BOUND
JL rangeError
CMP EBX, UPPER_BOUND
JG rangeError
JL valid
rangeError:
MOV EDX, OFFSET outOfRange
call WriteString
JMP ending
valid:
MOV EAX, 1
MOV validNum, EAX
ending:
ret
validate ENDP
showPrimes PROC
MOV EBX, userInput ; set EBX to number of primes
MOV ECX, 0 ; counter, start at 0
MOV EAX, 2 ; EAX starts at 2 because it is the first prime
printPrime:
; checks if the current number is a prime number
PUSH EAX ; push current number to stack
CALL isPrime
POP EAX ; restores number from stack after it is checked by isPrime
CMP EAX, 1 ; check if the number is prime
JNE notPrime ; if it's not prime, skip displaying
; display the prime number
CALL WriteDec
MOV EDX, OFFSET spacer
call WriteString
INC ECX ; increment prime count
; after 10 primes have been printed, make new line and reset the count
CMP ECX, 10
JNE nextPrime ; go to next prime if 10 have not been displayed
CALL CrLf
MOV ECX, 0 ; reset count
CMP ECX, EBX ; see if enough primes have been displayed based on the user input (EBX)
JL printPrime ; display the next prime if not
ret
nextPrime:
INC EAX ; move on to the next number by incrementing EAX
JMP printPrime
; if not prime just move on to the next number
notPrime:
INC EAX
JMP printPrime
ret
showPrimes ENDP
isPrime PROC
MOV ECX, 2 ; checking for the primes will start at 2
; 1 does not count as prime, so jump to notPrime if that is the case
CMP EAX, 1
JLE notPrime
checkDivisor:
; divide the number in EAX by the current divisor (ECX) and if there is
; no remainder, then the number is not prime, so jump to notPrime
MOV EDX, 0
DIV ECX
CMP EDX, 0
JE notPrime
; increment the divisor and see if we have checked all possible divisors
; when we compare, if total number of divisors is great than the input (ECX > EAX), it's prime
INC ECX
CMP ECX, EAX
JG prime
JMP checkDivisor
notPrime:
MOV EAX, 0
ret
prime:
MOV EAX, 1
ret
isPrime ENDP
farewell PROC
MOV EDX, OFFSET certified
call WriteString
ret
farewell ENDP
END main