I'm attempting to complete a program that takes an unsigned 32-bit integer from user input and tells the user if the number is or isn't prime. I have succeeded in inputting a number--InputNumber
--and I have succeeded in using 0 to end the program, but I am struggling with my isPrime
procedure, which takes a number n
and checks to see if it is prime or not. I keep receiving the error "IntegerOverflow" at line 122 (or div eax
), which is supposed to be the result of dividing ECX by 2 in order to make a maximum divisor for n
. I'm not sure what else I've done wrong, but it's currently the only error that I've seen (as Visual Studio comes to a grinding halt at line 122). My code is listed below.
TITLE Determine Whether Number is Prime, Version 1 (isPrime.asm)
; This program takes 32-bit unsigned
; integers and sees if they are prime numbers;
; it also displays the time taken to determine
; this information.
; Name: Kasizah
; Date: 11-07-2022
INCLUDE Irvine32.inc
.data
dPrompt BYTE "Enter a non-negative integer (0 to exit): ",0
n DWORD ?
; time data
startTime DWORD ? ; start time
timeTaken DWORD ? ; time taken to perform process
; message strings
notPositive BYTE "ERROR: 'n' must be positive.",0
numPrime BYTE " is a prime number.",0
notPrime BYTE " is not a prime number; it is divisible by ",0
endstr BYTE ".",0
nEqualsOne BYTE "1 is not a prime number.",0
timeTakenSt BYTE "This computation took ",0
timeTakenEn BYTE " milliseconds.",0
.code
main PROC
input:
call InputNumber ; checks to see if number is zero
cmp n,0 ; compare value to zero
jl LTZError ; go to process for error message that
; states that number must be positive
ja process ; if positive, jump to process
jmp quit ; else number is zero
LTZError:
mov edx,OFFSET notPositive ; state that 'n' must be positive
call WriteString
call Crlf ; jump to next line
jmp input ; return to input
process:
call GetMseconds ; get start time
mov startTime,eax
cmp n,1 ; if 'n' is 1, jump to notPrimeNum
je numIsOne ; jump to numIsOne
call isPrime ; else call isPrime to see if number is prime
; jump based on whether or not 'n' is prime
cmp eax,0
jz primeNum ; EAX is 0, number is prime
jmp notPrimeNum ; else, say that number isn't prime
; PRIME OR NOT PRIME STATMENTS
primeNum:
mov eax,n ; number is prime
call WriteInt
mov edx,OFFSET numPrime ; state that number is prime
call WriteString
call Crlf ; jump to next line
jmp getTime ; jump to getTime
notPrimeNum:
mov ebx,eax ; copy number stored in EAX
mov eax,n ; write 'n'
call WriteInt
mov edx,OFFSET notPrime ; load notPrime into EDX
call WriteString
mov eax,ebx ; move EBX back into EAX
call WriteInt
mov edx,OFFSET endstr ; move endstr into EDX
call WriteString
call Crlf ; jump to next line
jmp getTime ; jump to getTime
numIsOne:
mov edx,OFFSET nEqualsOne ; load nEqualsOne into EDX
call WriteString
call Crlf ; jump to next line
jmp getTime ; jump to getTime
; SEE HOW MUCH TIME WAS TAKEN
getTime:
call GetMseconds ; get process end time
sub eax,startTime ; subtract startTime from time received
mov ebx,1000 ; multiply EAX by 1000
mul ebx
; output time taken
mov edx,OFFSET timeTakenSt ; load timeTakenSt into EDX
call WriteString
call WriteInt ; output time as integer
mov edx,OFFSET timeTakenEn ; load timeTakenEn into EDX
call WriteString
call Crlf ; jump to next line
jmp input ; return to input
quit:
exit ; exit the program
main ENDP
;----------------------------------------------
InputNumber PROC
;
; Prompts the user to input a number. The
; number is saved for later use.
; Receives: nothing
; Returns: nothing
;----------------------------------------------
mov edx,OFFSET dPrompt ; display prompt
call WriteString
call ReadInt ; reads 32-bit integer in from keyboard
mov n,eax ; move EAX into n
ret
InputNumber ENDP
;----------------------------------------------
isPrime PROC
;
; Takes a 32-bit number and determines if
; it is prime.
; Receives: EAX
; Returns: EAX
;----------------------------------------------
mov edx,n ; move 'n' into EDX
mov eax,2 ; move 2 into EAX
div eax ; divide EDX by 2
mov ecx,eax ; move EAX into ECX
check_loop:
mov eax,n ; move 'n' into EAX
xor edx,edx ; reset EDX to 0 so that it doesn't interfere
div ecx ; divide EAX by ECX
test edx,edx ; testing EDX against itself will set the zero flag
; if EDX is zero
jz not_prime ; EDX is zero, jump to not_prime
cmp ecx,1 ; else check to see if ECX is 1
je end_loop ; if 1, end loop
not_prime:
mov eax,ecx ; store ECX in EAX
jmp quit ; quit process
end_loop:
mov eax,0 ; as loop ran until ECX equaled 1, 'n' must
; be prime; set EAX to 0
jmp quit ; quit process
quit:
ret
isPrime ENDP
END main