%INCLUDE "csci224.inc"
;EX1_1: prime number calculator
;Tested to work with numbers up to 100000000.
SEGMENT .data
prompt: DB "Please enter an integer to see all prime numbers up to that integer.",10,0
prompt2: DB "Primes: ",10,0
SEGMENT .text
main:
mov edx, prompt ;Queue prompt for printing
call WriteString ;Print prompt
call ReadInt ;Get user input
mov edx, prompt2 ;Queue prompt for printing
call WriteString ;Print prompt
mov ecx, eax ;Move user number to loop counter
L1:
push ecx ;Push number in question into stack
call prime ;See if number is prime
JNC .L2 ;Carry bit not set, number wasn't prime
mov eax, ecx ;Move number to eax register for printing
call WriteInt ;Number was prime, print it out
Call Crlf ;Clean line
clc ;Clear carry bit
.L2: ;Prime method determined number wasn't prime
loop L1 ;Loop
ret
;----------------------------------------------------------------------
prime:
push ebp ;Stack Frame
mov ebp, esp
push eax ;Save all registers
push ebp
push ecx
push edx
push esi
mov eax, [ebp+8] ;Move parameter to register
call root ;Move the square root of n into ecx to use for the loop counter
mov esi, eax ;Move number to be tested into a register unaltered by the division process.
dec ecx ;ECX = n - 1
cmp ecx, 0 ;Was 1 or 0 passed to the function?
jle .L3 ;Yes, exit
.L1: ;Main Loop
cmp ecx, 1 ;Is the denominator 1
je .L4 ;Yes, no need to check if it divides evenly
mov eax, esi ;Numerator = prime
sub edx, edx ;Zero out register as a place holder for division
mov ebx, ecx ;Denominator = ecx, 1 < ecx < n
div ebx ;EDX = remainder, EAX = quotient
cmp edx, 0 ;Is the remainder 0?
je .L2 ;If remainder is zero, break
loop .L1 ;Loop to next integer
.L4: ;Prime number discovered
stc ;Remainder was never zero, number is prime
jmp .L3 ;Exit prime method
.L2: ;Number is not prime
.L3: ;Exit
pop esi ;Restore all registers
pop edx
pop ecx
pop ebp
pop eax
pop ebp
ret 4
;-----------------------------------------------------------------------------------------------------------------------
root: ;Square root appropriator from HW2.
;The rounding is incorrect, so 10^(1/2) is 4 instead of 3.
push eax ;Save used registers
push ebx
push ecx
push edx
push esi
; ecx = n | esi = r
mov ecx, eax ;Store number from prime method in ecx
mov edx, 1 ;edx = 1
loopp:
mov eax, esi ;Move r into register for calculation
mov ebx, esi ;Move r into register for calculation
mul ebx ;Square r
cmp ecx, eax ;Is r^2 > n
jle found ;Integer part of square root has been found
inc esi
jmp loopp ;Keep searching
found:
mov ecx, edx ;Move root to ecx to use in method prime
pop esi ;Restore used registers
pop edx
pop ecx
pop ebx
pop eax
ret