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
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
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
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
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
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
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
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
ASKER
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
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
ASKER
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
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
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
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
ASKER
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
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
* 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
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
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
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
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