Primes
 CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com

1. ## Primes

Hello again I am writing a program that takes the users input and finds that many primes; not the primes of the number from the user just that many.

The problem is when I input the amount of primes to generate I don't get all the values from primes variable which I am storing the primes. I know that there are values included that are not prime I just can't get an output other than the first part of primes variable.

RESULTS
If 0 is entered then output: There are no prime numbers.
If 1 is entered then output: The prime numbers are: 2
If 2 or greater is entered then output remains: The prime numbers are: 2
But it should include 2,3,5,7,9,11...etc (yes I know that 9 is not a prime, I am just trying to div by 2 and check if there is a remainder or not)
Code:
```; name: Nick Galewski
;
;
; Description: This code will generate the first X number of prime numbers,
;    where X is asked for as program input. You will need to handle any
;    input from 1 up to and including 5000 primes.
;
; Compiling this code for 32-bit use:
;    nasm -f elf file.asm
;    gcc -m32 -o file file.o
;
%define  SYS_EXIT   1
%define  SYS_WRITE  4

%define  STDIN      0
%define  STDOUT     1
%define  STDERR     2

%define  MAX_NUMBER   5000 ; The amount of numbers to hold
;~.~. Initialized data: .~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.
SECTION .data

prompt1: db 10, "Hello, for prime numbers to be generated please enter desired number. " , 10
prlen1:  equ \$-prompt1
format1: db "The prime numbers are: %d. ", 10, 0
format2: db "There are no prime numbers. ", 10, 0
flen:    equ \$-format2
inputf:  db "%d", 0
;~. Uninitialized data: .~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.
SECTION .bss
input:    resd MAX_NUMBER  ; user input the amount of primes to be displayed
numCount: resd 3               ; current number to check for prime
pCounter: resd 1                ; number of primes currently found
divisor:  resd 2                   ; number used to find primes(if there is a remainder then prime)
primes:   resd MAX_NUMBER  ; store primes here
;~.~. Program code: .~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.
SECTION .text

; Place all your extern declarations in this area.
extern printf
extern scanf
global main                            ; specify starting with main

;~.~. Subroutines: ~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.
; Place all your subroutine code in this area.

;~.~. Procedures: .~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.
; Place all your non-main procedure code in this area.

;~.~. The starting function: ~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.
main:
nop                                    ; this satisfies some compilers

PromptUser:
mov EAX, SYS_WRITE
mov EBX, STDOUT
mov ECX, prompt1
mov EDX, prlen1
int 80H

GetInput:
push input
push inputf
call scanf

Precondition:
cmp DWORD[input], 0   ; compare if input is zero
JZ Error                      ; jump when ZF set to Error label
cmp DWORD[input], 1   ; compare if input is 1
JZ P4                         ; jump when ZF set to P4 label
mov DWORD[primes], 2  ; move 2 into primes memory location for first prime
mov ESI, 0                  ; move 0 into ESI will represent  current position in primes memory location
mov ECX, divisor          ; move the divisor into ECX
P1:
mov EAX, DWORD[numCount] ; move input into EAX
div ECX                              ; Divide by ECX, and remainder is in EDX
cmp EDX, 0                         ; check if remainder is equal to 0
JZ P2                                 ; jump when ZF is set to P2 label
INC ESI                              ; increment ESI for primes position
mov EAX, DWORD[numCount] ; move input into EAX
mov DWORD[primes + ESI * 4], EAX ; Store value from EAX into the next position in primes
cmp DWORD[input], ESI         ; compare if ESI equals input
JZ P5                                 ; jump when ZF is set to P5 label

P2:
INC DWORD[numCount]        ; increment numCount to check next number for primeness

P3:
INC DWORD[numCount]        ; increment numCount to check next number for primeness
mov EAX, DWORD[numCount] ; move this next number into EAX

P4:
mov EAX, 2                        ; move 2 into EAX representing the first prime( can't divide 2 by 2 it the only even prime and won't give me a remainder)

P5:
mov EAX, DWORD[primes]     ; move all values found in prime to EAX(this is where I think my error is I don't know how to display all the numbers in the stack that I have found?)
Error:
push format2                      ; push message
call printf                           ; printf call
ret                                    ;return

Display:
push EAX                          ; push values found (error I just keep getting 2 as my only prime?)
push format1                      ; push message
call printf                           ; printf call
ret                                    ; for main instead of exit
nop
;~_~_~ (end of file) _~_~_~_~_~_~_~_~_~_~_~_~_~_~_~_~_~_~_~_~_~_~_~_~_~_~_```
Thanks guys for all help and pointers

2. ## Re: Primes

You seem to have some misconception about the capabilities of the C printf() here. It doesn't even support outputting an entire array of integers in a single call. The "%d" format specifier outputs a single integer it finds on the stack and that's it. You'd need another loop to get more. And even if printf() could do something like that, you're not giving it enough information to be able to do so: You're pushing a single int onto the stack and neither give it the address nor the size of your array.

Also, if

Code:
`        numCount: resd 3               ; current number to check for prime`
allocates a single DWORD and initializes it to the value of 3, then

Code:
`        primes:   resd MAX_NUMBER  ; store primes here`
would allocate a single DWORD and initialize it to the value of 5000. Or am I misunderstanding something here myself? Admittedly I don't have any personal experience with NASM.

Finally, you initialize the array index in ESI to 0 and then increment it before writing the prime you found into the array. That way you'd leave the first entry of the array unused and in exchange eventually overwrite the end of the array by one DWORD.
Last edited by Eri523; November 16th, 2012 at 02:25 AM.

3. Member
Join Date
Aug 2009
Location
Posts
141

## Re: Primes

Im not up on nasm either but I think Eri523 hit it right on the head, it looks like youre creating a single dword value instead of an array which means your:

mov DWORD[primes + ESI * 4], EAX

statement would be overwriting memory that youre not expecting to change (the values youre storing there may or may not remain there)

Also, if you want it to find true prime numbers, all you have to do is have it divide the possible prime by each of the found prime numbers (technically you only need to check up to the square root of the number but that just adds complexity), and check edx for 0. Thats what I used till I finally implemented a few of the popular tests.

4. ## Re: Primes

Originally Posted by AKRichard
[...] (technically you only need to check up to the square root of the number but that just adds complexity), [...]
Not necessarily. I (and others) have elaborated on that and some other nifty prime testing details in an IMO rather interesting thread in the Non-VC++ section some time ago. But I decided to leave discussion regarding the actual prime detection algorithm to a bit later, since, as I interpreted the OP, that wasn't the primary problem at the moment.
Last edited by Eri523; November 19th, 2012 at 05:56 PM.

5. Member
Join Date
Aug 2009
Location
Posts
141

## Re: Primes

Originally Posted by Eri523
Not necessarily. I (and others) have elaborated on that and some other nifty prime testing details in an IMO rather interesting thread in the Non-VC++ section some time ago. But I decided do leave discussion regarding the actual prime detection algorithm to a bit later, since, as I interpreted the OP, that wasn't the primary problem at the moment.
ya, I read that he wasnt overly concerned about true primality. Interesting link you provided though. I had never even thought of just comparing the quotient to the factor, simple and effective, I love it. Not to mention a lot faster than calculating the square root.

#### Posting Permissions

• You may not post new threads
• You may not post replies
• You may not post attachments
• You may not edit your posts
•