Link to home
Start Free TrialLog in
Avatar of KevyKev003
KevyKev003

asked on

DETERMINE IF USER INPUT IS A PRIME NUMBER

Whats up...

Im new to assembly and need to write a program that will accept user input (number up to 10,000) and determine if that number is prime or not...
Not quit sure how to handle this... What register do I load you user input into.. and how to determine is its prime or not...

Any help would be greatly appreciated.. and on a tight deadline.. :(

KevyKev003
Avatar of billious
billious

Looks awfully like "Assignment Deadline".

Conceptually, you have two main choices:

   Brute-force: get the number in a register, then divide it by each number in the range 1..(half-your-input) and see whether any divisor gives you a remainder of 0.

  Lookup Table : Establish a table of prime numbers less than 10,000 and serially search through the table. You should be able to find such a table on the Web.

Since this appears to be a homework assignment, perhaps you should post your "accept a number from user" code to show you don't just want someone else to write your code.

...Bill


Avatar of KevyKev003

ASKER

Billious..

Thanks alot for the response... I figured it out... (finallY) .. i took the keyboard input in stored it into CX ... i divided by 2 and checked the remainder.. (prob1) in AH... but it was not there... after reading i found it was in the DX location... So obvious if rem = 0 .. then not prime..
then i subtracted 1 from the keyboard value.. and divided into the original amount.. ex . .input = 20 ... divisor=19 .. then div 20/19 ... and check remainder... decrement divisor... until down to 2... if no rem values of 0... then a prime number... This is the "brut force and ignorance" way..

2.   To make it a little more efficient.. once the div the input by 2... i started a counter at 3.. and divided 3 into the user input... each time i incremented the count by + 2 .. so divisor is all odd numbers... and i incremented until >= the median number after the original divide instruction.. so if no remainders of 0... a prime number... this way reduced the iterations .. .considerably... considering the max number allowed for the user is 10,000...    


thanks..

KevyKev003
ASKER CERTIFIED SOLUTION
Avatar of billious
billious

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Billious...

Thanks much for the code... i have it just about working perfectly... the only thing... im using a prompt to hold the user data of size (4) char...like
STARTNUM    BYTE      4 DUP(' ')   from within Paralist... then i use an int 21 to capture user data...  I use a variable aculength .... to determine the actual size of the user input... once i have the user input... in startnum... i do a mov to : MOV   SI,STARTNUM+3... .. i do this to move a pointer to the right most character... and then i will read to the left.... the only problem... when the user enters ... 0001... it works perfectly...the output prints out the next 40 consec numbers.. and tells whether each one is prime or not... but when the user only enters 1 ... then the output starts with 2300 and then the next 40 numbers... if the user enters 2.. then the output is 3300 and then..... and 3  .. then 4300 .. and so on... i cant figure out how to handle this problem... the input is suppose to handle input of 4 digit number.... so 0001 good... just 1 bad...


Any help will be greatly appreciated...

KevyKev003
Hmmm... you're referring to labels within code you haven't posted. My ESP just isn't that good.

Since your code appears to work with 0001 but not with 1, then perhaps you should start with

STARTNUM BYTE 4 DUP('0')

It's unclear whether you are reading character-by-character into STARTNUM (where you could simply shift characters STARTNUM+1..3 left 1 byte to STARTNUM+0..2, then deposit your new character into STARTNUM+3) or whether you have free choice & can use INT21H/0AH or whether you really need to use STARTNUM at all and could simply accumulate the input character-by-character into a pure binary form (in a register or memory word)

Better if you post the code you are using to place the data into STARTNUM.

...Bill
Billious...  

Whats up... thanks for that first liner... i needed that after a long day of debugging.. ;)   here's my code....  The sample output is in the upper comments ..
This code was given to use by the instructor.. and it origianally was hard coded to start at 90... and then increment the next 15 consec numbers... we had to change it to accept user input ... up to 9999 and then give the next 40 consec numbers... The code did the even/odd for us.. but we had to add the prime stuff....

None of the other students are at a point that they can help me...   You've been a great help...

KevyKev003



TITLE       CDA3100 Summer 2003:  Project one due at 6:10PM on May 27, 2003
;PAGE 50,72
;***************************************************************************
;CDA3100 Project one:   PRIME NUMBERS
;
;The following code is designed for the Intel 80386 processors.
;
;Your assignment is in four parts.  However, I suggest your first step should be to save
;a copy of this file (project1.asm) to insure you have a backup.  Next, you should assemble
;the source file using MASM611 (i.e., 'ML /Fl /Zi project1.asm'). If everything works correctly,
;the assembler will produce three file (project1.exe, project1.obj, project1.lst).  Run the .EXE
;program in DOS mode to insure it works.  You will need to turn in a disk with your source file and
;the three file produce by the assembler. Also, a paper copy of source file need to be turn in alone with
;the paper copy from parts 1.
;
;   Part one: Read the Software Engineering Code of Ethics and Professional Practice
;
;            a. Take a look at web site: "http://www.acm.org/serving/se/code.htm"
;
;            b. Check out the full version and you will see eight PRINCIPLES.
;            Write a brief (i.e., five lines) summary of the principle that match the last
;            digit of your SSAN.  Example: If your SSAN ends with a 5, then write about
;            principle five.  If your SSAN ends with a zero then use one.  Also, if your
;            SSAN ends with a nine then use eight.  10pts
;
;      Part two:
;
;            a. Currently the program only print 15 numbers...Change it to print a report on 40 numbers.  5pts
;            NOTE: Change the heading as needed...
;
;            b. Currently the routine print out information on only one number per row.  Change the routine to
;            have two number per row.   See below for an example:  20pts
;
;            Number         Even/odd      Prime      |   Number  Even/odd      Prime
;            -------------------------------------------------------------
;              91            Odd                      No              92            even                          No
;              93                Odd                      No          |      94            even                    No
;              95            odd                        No                  96            even          No
 ;              97                odd                      Yes                 98            even                   No
;
;
;
;      Part three: Currently the program does not check for prime.  Change the routine so that it check for prime
;      and print out the correct information in the report.  In other words, the report should say "yes" or "no"
;      under prime not "Yes/No".   25pts
;
;
;      Part FOUR:
;
;            a. Currently, if the number is over 99 the routine does NOT print them out correctly.
;            Change the routine so that it can handle any number less then 10,000  10pts
;
;            b. Currently the routine print out 15 number starting with 91. Change the program to
;            to ask the user to type-in the starting number.  See page 141-144 on how to use the "INT 21H function 09H"
;       to prompt the user. 10pts.  NOTE: Change the heading as needed...
;
;            c. Read in the keyboard input from part 4b above using the "INT 21H" function "0AH" for input. (page 141-144) 20pts
;
;***************************************************************************

      .MODEL SMALL

;***************************************************************************
;
; Allocate a reasonable amount of space for the stack  (2k)
;
;***************************************************************************

STACK                  segment      para STACK 'STACK'
stk                        BYTE      256 dup ("STACK ")
STACK                  ends

DATASEG      segment      para public 'data'

;***************************************************************************
;
; Global variables go here (i.e., below this box)
;
;***************************************************************************

PARLIST                  LABEL      BYTE                  ;NAME PARAMETER LIST
MAXLEN                  BYTE      5                  ;  MAX LENGTH OF INPUT
ACTULEN                  BYTE      ?                  ;  NUMBER OF CHARS ENTERED
STARTNUM            BYTE      4 DUP(' ')            ;  ENTERED START VALUE
PROMPT                  BYTE      'ENTER A 4 DIGIT NUMBER FOR A REPORT: ', '$'
DIVR                  WORD      0
COUNT                  WORD      40
REM                  WORD      0
EVENX                  BYTE      'EVEN'
PRIMEN                  BYTE      'NO '
PRIMEY                  BYTE      'YES'

HEADING                  BYTE      0DH                  ;CARRIAGE RETURN EQU HEX ODH i.e., 13
                  BYTE      0AH                  ;LINE FEED EQUAL HEX OAH

                  Byte      0DH,0AH,' PROJECT ONE PROGRAM WRITE A REPORT FOR FORTY NUMBERS',0DH,0AH
                  Byte      80 DUP('_'),0DH,0AH,0AH
                  BYTE      10 DUP(' ')
                  BYTE      'NUMBER      EVEN/ODD     PRIME   |    NUMBER       EVEN/ODD     PRIME',0DH,0AH
                  BYTE      80 DUP('_'),0DH,0AH,'$'
;CONVERSION STUFF
ASCLENTH            EQU      4
ASCVALUE            BYTE      4 DUP(' ')
BINVALUE            WORD      0
MULTFACT            DW      1

ONE                  WORD      1

NUMBER                  WORD    00

ODD                  BYTE      'ODD '

TEN                  WORD      10

TWO                  WORD      2

YES                  BYTE      'YES'

NO                      BYTE    'NO'


ROW                  BYTE      12 DUP(' ')
ASC_NUM                  WORD      2 DUP(' ')

                  BYTE      8 DUP(' ')
EVEN_ODD            Byte      3 DUP(' ')

                  BYTE      9 DUP(' ')
PRIME                  Byte      3 DUP(' '),'$'


C_R                  Byte      0DH            ;CARRIAGE RETURN EQUAL HEX 0DH i.e., 13

LINE_FEED            Byte      0AH,'$'            ;LINE FEED EQUAL HEX 0AH

ZERO                  EQU            0

DATASEG                  ends

CODESEG                  segment      para public 'code'

                  assume      cs:CODESEG, ds:DATASEG,CS:CODESEG


;***************************************************************************
;
; Main is the main program.  Program execution always begins here.
;
;
;***************************************************************************

MAIN                  PROC      FAR      ;MAIN PROCEDURE

.386

;***************************************************************************
;
; set up the the segment registers:  You DON'T need to change this code
;
;***************************************************************************

            MOV            AX, DATASEG            ;GET ADDRESS OF DATA SEGMENT
            MOV            DS, AX                  ;PLACE THE DATA SEGMENT IN DS
            MOV            ES, AX

;***************************************************************************
;
; THE FOLLOWING LINES OF CODE WILL CLEAR THE SCREEN AND SET THE CURSOR
; You DON'T need to change this code
;***************************************************************************

            MOV            AX,0600H            ;SCROLL FULL SCREEN
            MOV            BH,07                  ;ATTRIBUTE: WHITE ON BLACK
            MOV            CX,0000                  ;UPPER LEFT LOCATION
            MOV            DX,184FH            ;LOWER RIGHT LOCA
            INT            10H                  ;CALL BIOS

;  SET CURSOR TO ROW 3, COL 0

            MOV            AH,02H                  ;LOAD AH WITH REQUEST SET CURSOR CODE
            MOV            BH,00                  ;PAGE NUMBER 0
            MOV            DX,0300H            ;ROW 3, COL 0
            INT            10H                  ;CALL BIOS

;***************************************************************************
;
; THE FOLLOWING LINES OF CODE PRINT OUT THE REPORT HEADING FOR THE PROGRAM
; AND ACCEPT USER INPUT
;***************************************************************************

A10:
                MOV            AH,09H                  ;DISPLAYS PROMPT
             LEA             DX,PROMPT
                INT            21H
                MOV            AH,0AH
                LEA            DX,PARLIST              ;CAPTURES INPUT FOR
                INT            21H

                CMP            ACTULEN,00
                JE            A10
                CMP            ACTULEN,01
                JE            A10
                CMP            ACTULEN,02
                JE            A10
                CMP            ACTULEN,03
                JE            A10
            MOV            AH,09H                  ;SET THE STAGE TO REQUEST USER INPUT
            LEA            DX,HEADING            ;LOAD ADDRESS OF DISPLAY TO PRINT OUT
            INT            21H

;CONVERSION ****

            MOV            CX,ASCLENTH
            LEA            SI,STARTNUM+3
L10:
            MOV            AL,[SI]
            AND            AX,000FH
            MUL            MULTFACT
            ADD            BINVALUE,AX
            MOV            AX,MULTFACT
            IMUL            AX,10
            MOV            MULTFACT,AX
            DEC            SI
            LOOP            L10
                MOV            AX,NUMBER
                ADD            AX,BINVALUE
;                DEC            AX
                MOV            NUMBER,AX


PRINT_ROW:
;***************************************************************************
;
; 1) ASSUME THE NUMBER IS EVEN.  SET UP TO MOVE THE CHARACTERS "EVEN" TO MEMORY
;    LOCATION "EVEN_ODD".
;
; 2) CHECK THE NUMBER FOR EVEN OR ODD BY DIVIDING BY TWO AND LOOKING AT THE
;    REMAINDER.  NOTE: THE REMAINDER IS IN REGISTER AH AFTER THE DIVID INSTRUCTION.
;
; 3) IF IT IS ODD SO SET UP TO MOVE THE CHARACTERS "ODD " TO MEMORY
;    LOCATION "EVEN_ODD".
;
; 4) MOVE CHARS TO REPLY MESSAGE.  TO "EVEN_ODD"
;
; 5) PRINT ROW
;
;***************************************************************************
            INC            NUMBER
            MOV            CX,ZERO
            MOV            BX,ZERO

;SOME STUFF

A20:
            MOV            AX,NUMBER

            MOV            DX,ZERO
            INC            CX
;            MOV            DIVR,CX
;            DIV            DIVR
            DIV            CX
            CMP            DX,ZERO
            JNE            NOT_EQUAL
            INC            BX
NOT_EQUAL:
            CMP            CX,NUMBER
            JNE            A20
                LEA            SI,PRIMEY
                CMP            BX,2
            JE            IS_PRIME
            LEA            SI,PRIMEN
IS_PRIME:
            MOV            CX,3
            MOV            BX,CX
LOOPTHIS:
             DEC            BX
             MOV            AL,[SI+BX]
             MOV            PRIME[BX],AL
             LOOP            LOOPTHIS
;STUFF ENDS
            LEA            SI,EVENX            ;ASSUME EVEN: LOAD ADDRESS OF DISPLAY TO PRINT OUT
            MOV            DX,ZERO                  ; CLEAR DX BEFORE THE DIVIDE
            MOV            AX,NUMBER            ; SET AX
            DIV            TWO
            CMP            DX,ZERO                  ; DX=ZERO THEN NUMBER IS EVEN
            JE            EVEN_NUMBER
            LEA            SI,ODD                  ;THE NUMBER IS ODD

;***************************************************************************
;
; MOVE "YES" OR "NO" TO "EVEN_ODD" IN THE ROW ANSWER
;
;***************************************************************************

EVEN_NUMBER:

            MOV            CX,4                  ; ONLY 4 CHARACTERS IN THE WORD "EVEN"
            MOV            BX,CX
LOOP10:
            DEC            BX                  ; BX POINT TO THE LAST CHARA
            MOV            AL,[SI+BX]            ; MOVE CHAR TO AL
            MOV             EVEN_ODD[BX],AL            ; PLACE CHAR INTO OUTPUT MESSAGE
            LOOP            LOOP10                  ; HAVE WE MOVED ALL CHAR?
                                          ; YES...



;*******************************************************************
;
;THE FOLLOWING CODE WILL CONVERT THE BINARY VALUE "NUMBER" TO ASCII
;FOR PRINTING, AND STORE THE ASCII CHARACTERS INTO THE FIRST TWO BYTES
;OF "ASC_NUM".
;
;*******************************************************************

;            MOV            AX,NUMBER            ;AX=NUMBER
;            DIV            TEN                  ;STORES THE REMAINDER IN AH AND QUOTIENT IN AL
;            OR            AX,3030H            ;EXAMPLE: 15 BECOME 3135(I.E., ASCII 15)
;            MOV            ASC_NUM,AX            ;MOVE AX TO ASCII FIELD
            MOV            CX,0010
            LEA            SI,ASC_NUM+3
            MOV            AX,NUMBER
L20:
            CMP            AX,CX
            JB            L30
            XOR            DX,DX
            DIV            CX
            OR            DL,30H
            MOV            [SI],DL
            DEC            SI
            JMP            L20
L30:
            OR            AL,30H
            MOV            [SI],AL

            LEA            DX,ROW
            MOV            AH,09H                  ;SET THE STAGE TO REQUEST USER INPUT
            INT            21H

            MOV            AX,COUNT
            MOV            DX,ZERO
            DIV            TWO
            DEC            COUNT
            CMP            DX,ZERO
            JE            SKIP
                LEA            DX,C_R
                MOV            AH,09H
                INT            21H
SKIP:
                MOV            AX,COUNT
            CMP              AX,00                  ;HAVE WE PRINTED ALL ROWS?
            JNE              PRINT_ROW            ;NO...SO DO THE NEXT ROW OF THE REPORT

STOP:
            MOV            AX,4C00H            ;SET UP SUBFUNCTION CODE TO STOP
            INT            21H                  ;END PROCESSING

Main            endp                              ;END OF MAIN PROCEDURE
            END            MAIN
Billious...

Oh yea.. .I forgot one thing... i've actually harded this program to only accept a 4 char number... (hey, im trying anything!)... with this code...
you can delete the 3 of 4 series of CMP statements...  

thanks... kevy


A10:
               MOV          AH,09H                  ;DISPLAYS PROMPT
          LEA           DX,PROMPT
               INT          21H
               MOV          AH,0AH
               LEA          DX,PARLIST              ;CAPTURES INPUT FOR
               INT          21H

               CMP          ACTULEN,00            ;checking that four digits were entered...
               JE          A10
               CMP          ACTULEN,01
               JE          A10
               CMP          ACTULEN,02
               JE          A10
               CMP          ACTULEN,03
               JE          A10


Consider this sequence:

PARLIST               LABEL     BYTE               ;NAME PARAMETER LIST
MAXLEN               BYTE     5               ;  MAX LENGTH OF INPUT
ACTULEN               BYTE     ?               ;  NUMBER OF CHARS ENTERED
STARTNUM          BYTE     4 DUP(' ')          ;  ENTERED START VALUE

It's very important that these bytes remain in precisely this sequence because this is a STRUCTURE in C-terms.

Pointing DS:DX to PARLIST and executing INT21H/0AH tells MSDOS to accept a string from the keyboard, with maximum length 5 (the contents of the first byte), placing the length received NOT INCLUDING the CR in ACTULEN (the second byte) and the character input into STARTNUM, with a CR character after the last character input

Consequently, the contents of the bytes will be (in HEX)
05 ?? 20 20 20 20 xx Start
05 00 0D 20 20 20 xx If just CR entered
05 00 31 0D 20 20 xx If 1 CR entered
05 00 31 32 0D 20 xx If 12 CR entered
05 00 31 32 33 0D xx If 123 CR entered
05 00 31 32 33 34 0D If 1234 CR entered

Note that there is a small problem here - the CR entered after 4 digits will overwrite the
first 'E' in 'ENTER A 4-DI....

Cure this by making STARTNUM a 5 DUP(' ') - actually, a 5 DUP(?) would probably be better since the original values are overwritten, so there's no point in establishing SPECIFIC values for these bytes.

So, this might explain the strange start values - you would add (given simply a '1' input)
20 & 0F = 00 = 0 * 1 +
20 & 0F = 00 = 0 * 10 +
0D & 0F = 0D = 13 * 100 +
31 & 0F = 01 = 1 * 1000
  = 1000 + 1300 + 0 + 0 = 2300 (look familiar?)

So, what you need to do is

while ACTULEN < 4 do
begin
  move STARTNUM+2 to STARTNUM+3
  move STARTNUM+1 to STARTNUM+2
  move STARTNUM+0 to STARTNUM+1
  move '0' to STARTNUM+0
  add 1 to ACTULEN
end

Your problem to find a smart way to do that... :)

STARTNUM will then have a 4-character string with leading '0' characters.

You may then be well advised to check that each character is numeric (a loop on the 4 resultant characters seems to be the way to go here, just check that they are >= '0' and <='9') - and then display an error message/return to prompt/get-input.

It might be a nice feature to have a 0-input length terminate the program.

HTH

...Bill


 
Damn - make that byte-sequence

Consequently, the contents of the bytes will be (in HEX)
05 ?? 20 20 20 20 xx Start
05 00 0D 20 20 20 xx If just CR entered
05 01 31 0D 20 20 xx If 1 CR entered
05 02 31 32 0D 20 xx If 12 CR entered
05 03 31 32 33 0D xx If 123 CR entered
05 04 31 32 33 34 0D If 1234 CR entered
---^^--- This column was wrong (lenth that was input before CR)

...Bill

Billious...

How's if going... thanks a bunch for the help... i finally figured it out... i used..

MOV            CX,ZERO                 ;CONVERTS INPUT TO BIN
            MOV            CL,ACTULEN
            MOV            AX,ZERO
            MOV            AL,ACTULEN
            DEC            AL
            LEA            SI,STARTNUM;+3
            ADD            SI,AX
L10:
            MOV            AL,[SI]
            AND            AX,000FH
            MUL            MULTFACT
            ADD            BINVALUE,AX
            MOV            AX,MULTFACT
            IMUL            AX,10
            MOV            MULTFACT,AX
            DEC            SI
            LOOP            L10
                MOV            AX,NUMBER               ;ADDS BIN VALUE TO NUMBER - NUMBER WAS INIT TO 0
                ADD            AX,BINVALUE
                MOV            NUMBER,AX


So no matter if input is .. 1. 11, 111, or 1111... My professor did not like the idea for forcing the user to enter a 4 digit number...  So fixing this was absolutly a must.... So im glad that's done.... My first assembly project... (oh boy)... and i complained about cobol.... :).. again thanks much for the help and the patience...

In the Spirit of Mutual Success

KevyKev003
There's a theorem that goes
* Every program is inefficient and can be shortened
* Every program contains at least one bug

The corrollary to which is that every program can be reduced to a single (Wrong) instruction.

On IBM Mainframes, there is a program called IEFBR14, which is designed to be a program which does precisely NOTHING.

AFAIR, it started out as a single instruction, but after two bugfixes it's now 3 instructions long.

And in that spirit,

MOV          CX,ZERO                 ;CONVERTS INPUT TO BIN
         MOV          CL,ACTULEN
         MOV          AX,ZERO
         MOV          AL,ACTULEN
         DEC          AL
         LEA          SI,STARTNUM;+3
         ADD          SI,AX

can be reduced to

         MOV          CX,ZERO                 ;CONVERTS INPUT TO BIN
         MOV          CL,ACTULEN
         LEA          SI,STARTNUM-1
         ADD          SI,CX

And even the

         MOV          CX,ZERO                 ;CONVERTS INPUT TO BIN

can be reduced to
         XOR          CX,CX                     ;0->CX

which is smaller and faster, if a little more obscure

:D

...Bill


...But I still think you should use 5 DUP(?) rather than 4 DUP(' ')

If you have your code terminate on an entry of ZERO, and loopback to start again after printing the results for any other input, then try your code with 4 input digits - the prompt for the next input should have the "E" missing from "ENTER 4 DIGITS....

...Bill
Hi,
I always thought that IEFBR14 did a 'BR   R14' (branch to where register 14 is pointing -- essentially exiting the program and returning control to the operating system).  That's more than a 'BR    R0' does!   :)

Ken
kenspencer:

Certainly. I've not worked on IBM for many years, so I'm a little hazy about it now, but IIRC BR R14 alone either set SEVERITY to RANDOM or to UNCHANGED. Now since it's a program that successfully executed, theory says it should return 0.

...Bill