The MASM Forum

General => The Campus => Topic started by: allen on February 24, 2014, 04:47:40 PM

Title: Need A little bit of help
Post by: allen on February 24, 2014, 04:47:40 PM
I'm Trying to create simple prime number i got it working but i do need some opinion.
i saw a prime chart where is 2      3      5      7     11     13     17     19     23     29
31    but my is  not prime 2 hope you could help me pinpoint where my problem is



[code].386
.model flat, stdcall
option casemap :none

include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\masm32.inc

includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\masm32.lib


.data


            Message1 db "Please Enter the first number: ", 0
            Message6 db " Is a prime number ", 0
            Message7 db " Is not a prime number ", 0
           

.data?

      Number1 dd 2 dup(?)
            Number2 dd 2 dup(?)
Number3 dd 2 dup(?)
Number4 dd 2 dup(?)
Number5 dd 2 dup(?)



.code
start:

        invoke StdOut, addr Message1
        invoke StdIn, addr Number1, 100
        invoke StripLF, addr Number1
       
       

       
       
    invoke atodw, addr Number1
    mov ecx, eax
    mov ebx, 2
    mov eax,ecx
    idiv ebx
    cmp edx, 0
    jne NOTPRIME
   
    invoke StdOut, addr Number1
    invoke StdOut, addr Message6
   
     jmp EXT
   
NOTPRIME:
   
    invoke StdOut, addr Number1
    invoke StdOut, addr Message7
     

EXT:



    invoke ExitProcess,0



End start


[/code]
Title: Re: Need A little bit of help
Post by: jj2007 on February 24, 2014, 05:17:33 PM
Hi Allen,

Have you ever seen the ";" (semicolon) character in source code here at the Masm32 forum?

It is extremely useful. It means "and here I explain what my code does, or at least what I wished it would do".

Please repost your code, and use ";" a lot.
Title: Re: Need A little bit of help
Post by: allen on February 24, 2014, 05:25:45 PM
Sorry  im still new at the forum  my code is already running but. i just wanna know if my code is correct on is checking prime


OUTPUT

Is a prime number: 2
Is a prime number: 3

BUT MY OUTPUT 

Is not a prime number:2
Is a prime number: 3

Title: Re: Need A little bit of help
Post by: GoneFishing on February 24, 2014, 08:12:35 PM
Quote from: allen on February 24, 2014, 05:25:45 PM
... i just wanna know if my code is correct on is checking prime ...
Obviously not:
QuoteA prime number is a number that cannot be divided by a number other than 1 and itself
As I have no math background it would be great if you explained us how to check whether the number is prime .
Title: Re: Need A little bit of help
Post by: RuiLoureiro on February 24, 2014, 10:26:53 PM
Hi Allen,

    1) You are working with positive integers

    2) As vertograd wrote
   
       «A prime number is a number that cannot be divided
        by a number other than 1 and itself»       
       and
       «all even numbers can be divided by 2»

    So, if the number is > 2 than if it is even than it is not
    a prime number

    3) Dont use  Message6 and Message7

       Use
           MessageIsPrime   or MsgIsPrime
       and
           MessageNotPrime  or MsgNotPrime

       Follow what jj2007 wrote:

            «Please repost your code, and use ";" a lot.»
           
   
    4) When we want to divide EAX by EBX
       we use

                xor     edx, edx
                div     ebx                             ; divide EDX:EAX by EBX
                or      edx, edx
                jz      notprime
               
                sub     ebx, 1                       ; if it is 1 => ???
                ;---------------------
                ;     go on ?
                ;---------------------
    notprime:

    Good luck  :t
Title: Re: Need A little bit of help
Post by: dedndave on February 24, 2014, 11:32:38 PM
hi Allen,

it's not uncommon to write prime sieve code that works for all but the first few values,
then go back and do "fix-ups" on those

to fix this, just treat 2 as a special case
Title: Re: Need A little bit of help
Post by: GoneFishing on February 25, 2014, 12:12:06 AM
Also test your code with such numbers as 15,21,25,27 etc. and post the results here, please

I'd recommend you  to read on Trial division (http://en.wikipedia.org/wiki/Trial_division) method as "the most laborious but easiest to understand " .
Here's a quick example in MASM32 style:

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
  include \masm32\include\masm32rt.inc
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

  IsEven proto :dword

  EVEN? MACRO val           ; a wrapper for IsEven procedure call
  invoke IsEven,val 
  EXITM <eax> 
  ENDM       

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

.data

     num dd 2               ; starting point for generation of the numbers

.data?

     PRIME BOOLEAN ?        ; flag , when set indicates the prime-ness of the number

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

.code
     start:
            call main
            inkey
            exit

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

main  proc

.while num <= 10            ; the end point for generation of the numbers

     .if num == 2           ; special case to be handled, 2 is both an even and prime number
     
         mov PRIME, TRUE    ; the flag is set to indicate that 2 is a prime number
     
     .else
     
         .if EVEN?(num)     ; all the rest even numbers are not primes
         
             mov PRIME, FALSE
         
         .else
     
             mov PRIME, TRUE ; the flag is set
     
             mov ecx,2       ; notice that we use not optimal algo of trial division here : 
                             ; we loop through the full range [2, num - 1] of divisors for num integer
            .REPEAT           
                   xor edx,edx
                   mov eax,num
                   div ecx
                   .if edx == 0          ; if the remainder is zero
                       mov PRIME, FALSE  ; the flag is cleared
                   .endif
                   inc ecx
            .UNTIL ecx <= num - 1
           
         .endif
         
     .endif 
     
     .if  PRIME
          printf("%d is a prime number\n",num)
     .else
          printf("%d is not a prime number\n",num)
     .endif

      inc num

.endw

ret

main endp

; ------------------------------------------------------------------------
; Name: IsEven
; Desc: performs Odd/Even check
;   In: integer value to be checked
;  Out: TRUE  if the integer value is even
;       FALSE if the integer value is odd
; ------------------------------------------------------------------------
; see http://www.masmforum.com/board/index.php?PHPSESSID=786dd40408172108b65a5a36b09c88c0&topic
; thread in the Old Masm32 Forum

IsEven proc value:dword
        test value,1
        .if ZERO?
            mov eax, TRUE
        .else
            mov eax, FALSE
        .endif
        ret         
IsEven endp

end start 

Monday, February 24, 2014 7:41:10 AM         


NOTE: it uses full-range trial division : [2, num-1] (not optimal)
Title: Re: Need A little bit of help
Post by: RuiLoureiro on February 25, 2014, 04:35:21 AM
Quote
; see http://www.masmforum.com/board/index.php?PHPSESSID=786dd40408172108b65a5a36b09c88c0&topic
; thread in the Old Masm32 Forum

IsEven proc value:dword
        test value,1
        .if ZERO?
            mov eax, TRUE
        .else
            mov eax, FALSE
        .endif
        ret         
IsEven endp

Hi vertograd,
                we dont need to call IsEven procedure

                When we have EAX, do this:

Quote
                test    eax, 1
                jz       notprime        ; is even

                xor     edx, edx
                div     ebx
                or      edx, edx
                jz      notprime
               
                sub     ebx, 1          ; if it is 1 => ???
                ;---------------------
                ;     go on ?
                ;---------------------
    notprime:
Title: Re: Need A little bit of help
Post by: GoneFishing on February 25, 2014, 04:41:28 AM
Hi Rui,

IsEven proc and EVEN? macro were designed specifically for this sample:

.if num == 2             
         mov PRIME, TRUE       
     .else     
         .if EVEN?(num)                                ; JUST FOR CONVINIENCE ;-)         
             mov PRIME, FALSE         
         .else     
             mov PRIME, TRUE
...
Title: Re: Need A little bit of help
Post by: allen on February 25, 2014, 03:31:17 PM
                xor     edx, edx
                div     ebx
                or      edx, edx
                jz      notprime
               
                sub     ebx, 1   

i tried using this code but i end up with this is

OUTPUT

2 Is a prime number
3 Is not a prime number
3 is a prime number
4 is not a prime number
Title: Re: Need A little bit of help
Post by: dedndave on February 25, 2014, 04:26:00 PM
as instructions go, DIV is one of the slow ones
you should read up a little on different sieves
the place almost everyone starts, is the Sieve of Eratosthenes

http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes (http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes)

Title: Re: Need A little bit of help
Post by: allen on February 25, 2014, 06:49:29 PM
im trying to understand and create a new one but instead im stuck can't figure out

.386
.model flat, stdcall
option casemap :none

include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\masm32.inc

includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\masm32.lib


.data


            Message1 db "Please Enter the first number: ", 0
            NotPrime db 'is not prime',0
            IsPrime db 'is prime',0
           

.data?

      Number1 dd 2 dup(?)
           


.code
start:

        invoke StdOut, addr Message1
        invoke StdIn, addr Number1, 100
        invoke StripLF, addr Number1
     
       
       
        invoke atodw, addr Number1
        mov ecx, eax
        mov ebx, 2
        mov eax,ecx
        xor edx,edx ;clear out edx
        idiv ebx
        cmp edx, 0 ; Check if remainder is 0
        jne Step1 ; if its anything but 0 jmp to next step

Step1:

      cmp ecx,1
      mov esi,ecx ;use esi as our incremental divisior
      sub esi,1 ;subtract 1 from esi
      cmp esi,1 ; is esi 1 (if its this far then yes its prime)
      je PrimeJump ;print prime
      mov eax,ecx  ;move our  number to eax for div
      xor edx,edx ;clear out edx
      div esi   ;eax/esi (number/mumber)   
      cmp edx,0 ;is remainder (edx) 0? this means it divided evenly (4/2 == remainder of 0 and 4 is not prime)
      je NonPrimeJump ;if it is, inform our user we are nolonger prime

PrimeJump:

        invoke  StdOut, addr IsPrime   
        invoke  StdOut, ecx

NonPrimeJump:
        invoke  StdOut, addr NotPrime
        invoke  StdOut, ecx
   
    invoke ExitProcess,0


End start

Title: Re: Need A little bit of help
Post by: TWell on February 25, 2014, 08:41:45 PM
This corrects one an obvious error:
PrimeJump:
        invoke  StdOut, addr IsPrime   
        invoke  StdOut, ecx
        jmp      ExitJump
NonPrimeJump:
        invoke  StdOut, addr NotPrime
        invoke  StdOut, ecx
ExitJump:
    invoke ExitProcess,0
Title: Re: Need A little bit of help
Post by: RuiLoureiro on February 25, 2014, 10:36:48 PM
Quote from: allen on February 25, 2014, 03:31:17 PM
                xor     edx, edx
                div     ebx
                or      edx, edx
                jz      notprime               
                sub     ebx, 1   
i tried using this code but i end up with this is

OUTPUT

2 Is a prime number
3 Is not a prime number
3 is a prime number
4 is not a prime number

Of course, you need to do something else, Allen.

Does this work ?

        or          eax, eax
        jz          NOTPRIME
        cmp         eax, 1
        je          NOTPRIME            ; but it is divided by 1 and itself

        cmp         eax, 2
        je          ISPRIME
       
        test        eax, 1
        jz          NOTPRIME            ; is even
       
        ;--------------------------------
        ;        eax is > 2
        ;--------------------------------
        mov         ebx, eax
       
  @@:   sub         ebx, 1              ; start at eax-1
        cmp         ebx, 1
        je          ISPRIME

        mov         ecx, eax            ; save eax is = ecx
       
        xor         edx, edx
        div         ebx
        or          edx, edx
        jz          NOTPRIME

        mov         eax, ecx            ; set eax=ecx
        jnz         short @B


Title: Re: Need A little bit of help
Post by: RuiLoureiro on February 26, 2014, 04:48:32 AM
Quote from: dedndave on February 25, 2014, 04:26:00 PM
as instructions go, DIV is one of the slow ones
you should read up a little on different sieves
the place almost everyone starts, is the Sieve of Eratosthenes

http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes (http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes)

Hi Dave,
              It seems to be a complex task to him.   :t
Title: Re: Need A little bit of help
Post by: GoneFishing on February 26, 2014, 05:13:42 AM
I found MS VS C++ sample PRIMESSTEP2 (http://msdn.microsoft.com/en-us/library/ke1dc46c(v=vs.90).aspx) (mixed C and ASM)
Stepped through the asm code line by line  - it's perfect  :t
I've even generated 262144 byte raw file ( for visualization in 512x512 window )
(If anyone is interested in results - let me know and I'll post it)
Title: Re: Need A little bit of help
Post by: allen on February 26, 2014, 02:22:55 PM
Thanks everyone i just stick to my first simple broken code even i get  C- this semester it was eye opening experience masm  is truly hard. Thanks you guys were a big help and letting me understand masm better than my professor who lack to teach us anything just write down the all the instruction without discussing or explain to us what it does and give us 10 program to write the prime number. for me is the most hardest for me.because I totally failed at and MATH class and mostly i just copy from my friends when it comes to MATH
Title: Re: Need A little bit of help
Post by: dedndave on February 27, 2014, 03:49:27 AM
it's actually not that hard
there is just a lot of material to absorb   :P
Title: Re: Need A little bit of help
Post by: MDWLibby on February 28, 2014, 07:34:31 AM
Hi All

I'm new, (this is my 1st post).  Allen it seems is about to give up.  I hope no!  I to am just learning Asm.  It takes courage to post code and ask questions.  You people do well at helping the brave beginner, and I'm sure in the not to distant future I'll be posting my own questions and code.  I'm an old hack, the 1st time I was called a "Hacker", I took it as an insult.  In the last 6 months I have had to do much reading.  I'm from the days of Dos and MASM, that was back some 25 years ago.  I have done a little hobby programing in Power Basic in the last 10 years, and have decided to stretch out.  After 2 - 3 weeks of looking at Assemblers, I think I might have looked at all of them.  I have visited these Forum many times, and is one of the many reasons I have decided to use MASM again.

Thanks Allen for having the courage to ask.  Whether you stick to it or not, you have already help teach, (something your professor seams to lack).

Thanks All
Title: Re: Need A little bit of help
Post by: Gunther on March 01, 2014, 02:58:21 AM
Hi MDWLibby,

thank you for your courageous words and welcome to the forum.

Gunther
Title: Re: Need A little bit of help
Post by: GoneFishing on March 10, 2014, 02:32:18 AM
 Shame on me  :icon_redface:
Today I ran the code posted in my Reply#6 and suddenly discovered that numbers 9 ,15, 21 are listed as prime ones. I figured out that it was because of incorrect use of REPEAT - UNTIL  block:
Quote
                   mov ecx, 2

.REPEAT
     @@:         
                   xor edx,edx
                   mov eax,num
                   div ecx
                   .if edx == 0          ; if the remainder is zero
                       mov PRIME, FALSE  ; the flag is cleared
                   .endif
                   inc ecx
                   cmp ecx,num
                   jnz @B     
     .UNTIL ecx <= num - 1

P.S.: thank you guys that you were so polite and didn't  point  to my silly error   :t
   
Title: Re: Need A little bit of help
Post by: jj2007 on March 10, 2014, 03:40:41 AM
Interesting that neither MASM nor JWasm throw an error or at least a warning. In the disassembly, you can see that ecx <= num - 1 encodes as .UNTIL ecx <= num[-1] - which is clearly a different animal.

In contrast,

For_ ecx=0 To eax-1
   nop
Next

is entirely legal ;-)
Title: Re: Need A little bit of help
Post by: GoneFishing on March 10, 2014, 04:34:32 AM
Quote from: jj2007 on March 10, 2014, 03:40:41 AM
...
In the disassembly, you can see that ecx <= num - 1 encodes as .UNTIL ecx <= num[-1] - which is clearly a different animal.
...
Seems so .
Quote
00401074                    loc_00401074:               ; Xref 0040106B
00401074 41                     inc     ecx
00401075 3B0DFF2F4000           cmp     ecx,[off_00402FFF]
0040107B 77E3                   ja      loc_00401060

from WinDbg session:

; num = 3
00401076 3b0dff2f4000    cmp     ecx,dword ptr [image00400000+0x2fff (00402fff)] ds:002b:00402fff=00000300
; num = 5
00401076 3b0dff2f4000    cmp     ecx,dword ptr [image00400000+0x2fff (00402fff)] ds:002b:00402fff=00000500
; num = 7
00401076 3b0dff2f4000    cmp     ecx,dword ptr [image00400000+0x2fff (00402fff)] ds:002b:00402fff=00000700



This version works too :
Quote
.REPEAT           
                   xor edx,edx
                   mov eax,num
                   div ecx
                   .if edx == 0          ; if the remainder is zero
                       mov PRIME, FALSE  ; the flag is cleared
                   .endif
                   inc ecx
.UNTIL ecx == num  
Title: Re: Need A little bit of help
Post by: jj2007 on March 10, 2014, 04:50:09 AM
By the way,
   .if edx==0
is one byte longer than
   .if !edx
Title: Re: Need A little bit of help
Post by: GoneFishing on March 10, 2014, 05:11:26 AM
Thanks, Jochen
Good to know