OK, I found an error in your second program--your iteration loop is
not correct. The fixed code is below. Please compile and try:
.MODEL SMALL ;assembler directive
.STACK 200h ;necessary for space when int 21h is called
.DATA ;variables and constants
first_num DW 100d ;begin at 100
last_num DW 999d ;end at 999
myname DB 'this program is to find prime numbers from 100 to
999', 0Ah, 0Dh, 0Ah, 0Dh,'$'
done DB 'Done$'
crlf DB 0Ah, 0Dh, '$'
cr DB 0Dh, '$'
.CODE ;assembler directive
;first, establish access to the data segment by setting DS, in the
following 2-stage process
MOV AX,@DATA
MOV DS,AX
;Print headers
MOV DX, OFFSET myname
MOV AH, 9h ;code for print a string
INT 21h
MOV AX, 1 ;The first number
JMP FoundPrime ;One is prime, print it
NewNum: ;Next Number
INC AX ;Advance number
MOV BX, 1
BeginTest: ;Start test loop
INC BX ;Advance divisor
CMP AX, last_num ;Check if number = 999
JMP FINISH_PROGRAM ;EXIT
CMP AX, first_num ;Check if number < 100
JL Skip ;Skip
CMP AX, BX ;Check if number = divisor
JE FoundPrime ;If so, it's prime, loop finished
Skip:
MOV CX, AX ;Save the number
XOR DX, DX ;Zero high DWord of divisor
DIV BX ;Divide number by divisor
XCHG DX, CX ;Prep remainder for testing
MOV AX, DX ;Put number back
JCXZ NewNum ;If no remainder it's not prime
JMP BeginTest ;Next in test loop
FoundPrime: ;Print the prime number
MOV BX, AX ;Store current number
MOV SI, 10 ;Load divisor with 10
XOR CX, CX ;Zero digit count
NON_ZERO: ;Calculate digits
XOR DX, DX ;Zero high DWord of divisor
DIV SI ;Divide number by divisor
PUSH DX ;Put the digit on the stack
INC CX ;Add one more digit to count
OR AX, AX ;Check for end of loop
JNE NON_ZERO ;Next digit to print
MOV AX, BX ;Restore the current number
WRITE_DIGIT_LOOP: ;Print digits
POP DX ;Get digit in reverse order
ADD DL,"0" ;Add ascii 0 to the value
MOV SI, AX ;Store ascii value
MOV AH,2 ;Function 2h
INT 21h ;Print it
MOV AX, SI ;Restore the ascii value
LOOP WRITE_DIGIT_LOOP ;Next digit to print
MOV DL, " " ;A space
MOV CX, AX ;Store the current number
MOV AH,2 ;Function 2h
INT 21h ;Print it
MOV AX, CX ;Restore the test number
JMP NewNum ;Go next number
FINISH_PROGRAM:
END ;End address |
Request for Answer Clarification by
kffru-ga
on
16 Apr 2005 12:46 PDT
hi, studboy, thank you for your help
I am using Turbo Assembler version 1.0
when I typed "tasm try" and "tlink try" in command prompt, there were
no error and warning messages. However, when I typed "try", there was
a message showed in a small window
"16 bit MS-DOS Subsystem
Command Prompt-try
The MTVDM CPU has encountered and illegal instruction
CS:0550 IP:00d8 OP:db753683c6 Choose 'Close' to terminate the application"
Do you know what's wrong with this?
thanks
|
Clarification of Answer by
studboy-ga
on
16 Apr 2005 14:34 PDT
I believe this is the problem with the linker--
perhaps the linker is not linking the 16 bit application correctly.
Can you provide me access to your machine?
Or can you tell me more about your machine:
1) Does it compile/run the first program (first one you posted) fine?
2) Are you using Windows 98, 2000, ME, or XP?
3) What version of tasm are you using? Do you have a download link?
|
Clarification of Answer by
studboy-ga
on
16 Apr 2005 14:42 PDT
Also try assembling/running on a different machine if you have access to one--
it might be the compiler problem with this particular OS/processor.
|
Request for Answer Clarification by
kffru-ga
on
16 Apr 2005 14:54 PDT
1) when I ran the first program, the following was result
C:\TASM>tasm test
Turbo Assembler Version 1.0 Copyright (c) 1988 by Borland International
Assembling file: TEST.ASM
Error messages: None
Warning messages: None
Remaining memory: 488k
C:\TASM>tlink test
Turbo Link Version 2.0 Copyright (c) 1987, 1988 Borland International
Warning: no stack
C:\TASM>test
calculting .... 003 005 007 011 013 017 019 023 029 031 037 041 043 047 053 059
061 067 071 073 079 083 089 097 101 103 107 109 113 127 131 137 139 149 151 157
163 167 173 179 181 191 193 197 199 211 223 227 229 233 239 241 251 257 263 269
271 277 281 283 293 307 311 313 317 331 337 347 349 353 359 367 373 379 383 389
397 401 409 419 421 431 433 439 443 449 457 461 463 467 479 487 491 499 503 509
521 523 541 547 557 563 569 571 577 587 593 599 601 607 613 617 619 631 641 643
647 653 659 661 673 677 683 691 701 709 719 727 733 739 743 751 757 761 769 773
787 797 809 811 821 823 827 829 839 853 857 859 863 877 881 883 887 907 911 919
929 937 941 947 953 967 971 977 983 991 997 167
C:\TASM>
2) I am using Windows XP
3) I don't have download link. My professor send the assembler package to me.
I also ran in another computer. It's also Windows XP, and the result was same.
|
Clarification of Answer by
studboy-ga
on
16 Apr 2005 14:55 PDT
Also try using the latest 5.0:
http://eurosport.ifrance.com/joss/asmz.htm
For 32 bit windows tasm32 and tlink32 are preferred/more compatible.
|
Clarification of Answer by
studboy-ga
on
16 Apr 2005 14:57 PDT
I try to find the 1.0 you're using and there's no where to be found--
is it possible you can post the package up somewhere so I can download
to my Windows XP machine? Thanks
|
Clarification of Answer by
studboy-ga
on
16 Apr 2005 15:00 PDT
How about we try modifying the first program instead of the second one
as you requested? Seems like the second program won't run even
*without* my changes. Correct?
|
Clarification of Answer by
studboy-ga
on
16 Apr 2005 15:05 PDT
Try compiling this: first program modified:
max equ 999d ;highest number
print_m equ 9h ;print message function
doscall equ 21h ;DOS interrupt number
datarea segment ;define data segment
numbers db max dup (?) ;buffer for integers
mess1 db 'calculting ....$'
mess2 db ' $' ;one space
datarea ends
pro_nam segment ;define code segment
main proc far ;main part of program
assume cs:pro_nam,ds:datarea
start: ;starting execution address
;set up stack for return
push ds ;save DS on stack
sub ax,ax ;set AX to zero
push ax ;put on stack
;set DS to data segment
mov ax,datarea
mov ds,ax
;print initial message
mov dx,offset mess1
mov ah,print_m
int doscall
mov dx,offset mess2
mov ah,print_m
int doscall
;set count of primes to zero (CX register)
mov cx,0 ;set CX to zero
;fill odd numbers in array with zero
mov bx,100 ;start at 100
fill_0:
mov [numbers + bx],0
inc bx
inc bx
cmp bx,max
jle fill_0
;find primes, cross out all the nonprimes
mov bx,3 ;start with 3
;has this number been flagged as a nonprime?
search:
mov al,[numbers + bx]
cmp al,1
je go_next
;no, so it's a prime
;the semicolon can be removed from the
;following line to print out the primes
call binidec ;print the prime
inc cx ;count the prime
;cross out all the numbers that are multiples
;of this prime, by marking them "1"
mov si,bx ;j=i
cross_out:
add si,bx ;j=j+i
cmp si,max ;gone too far yet?
jg go_next ;yes
mov [numbers + si],1
jmp cross_out
;have we looked at all the numbers?
go_next:
inc bx ;skip to next
inc bx ;odd number
cmp bx,max ;are we done?
jle search ;not yet
;print out total number of primes and return
mov bx,cx ;put count in BX
call binidec ;print it
ret ;return from program to DOS
main endp ;end of main part of program
binidec proc near
;subroutine to convert binary number in BX
; to decimal on console screen
push bx ;save BX
push cx ;save CX
;print three spaces
mov dx,offset mess2
mov ah,print_m
int doscall
;divide by successive powers of 10d
mov cx,100d
call dec_div
mov cx,10d
call dec_div
mov cx,1d
call dec_div
pop cx ;restore CX
pop bx ;restore BX
ret ;return from binidec
dec_div proc near
;sub-subroutine to divide number in BX by
;number in CX, print quotinet on screen
mov ax,bx ;put number in AX
cwd ;AX into AX and DX
div cx ;divide by CX
mov bx,dx ;remainder into BX
mov dl,al ;quotient into DL
;print the contents of DL on screen
add dl,30h ;convert to ASCII
mov ah,2h ;display char function
int doscall
ret
dec_div endp
binidec endp
pro_nam ends ;end of code segment
end start ;end assembly
|
Clarification of Answer by
studboy-ga
on
16 Apr 2005 15:06 PDT
max equ 999d ;highest number
print_m equ 9h ;print message function
doscall equ 21h ;DOS interrupt number
datarea segment ;define data segment
numbers db max dup (?) ;buffer for integers
mess1 db 'calculting ....$'
mess2 db ' $' ;one space
datarea ends
pro_nam segment ;define code segment
main proc far ;main part of program
assume cs:pro_nam,ds:datarea
start: ;starting execution address
;set up stack for return
push ds ;save DS on stack
sub ax,ax ;set AX to zero
push ax ;put on stack
;set DS to data segment
mov ax,datarea
mov ds,ax
;print initial message
mov dx,offset mess1
mov ah,print_m
int doscall
mov dx,offset mess2
mov ah,print_m
int doscall
;set count of primes to zero (CX register)
mov cx,0 ;set CX to zero
;fill odd numbers in array with zero
mov bx,100 ;start at 100
fill_0:
mov [numbers + bx],0
inc bx
inc bx
cmp bx,max
jle fill_0
;find primes, cross out all the nonprimes
mov bx,3 ;start with 3
;has this number been flagged as a nonprime?
search:
mov al,[numbers + bx]
cmp al,1
je go_next
;no, so it's a prime
;the semicolon can be removed from the
;following line to print out the primes
call binidec ;print the prime
inc cx ;count the prime
;cross out all the numbers that are multiples
;of this prime, by marking them "1"
mov si,bx ;j=i
cross_out:
add si,bx ;j=j+i
cmp si,max ;gone too far yet?
jg go_next ;yes
mov [numbers + si],1
jmp cross_out
;have we looked at all the numbers?
go_next:
inc bx ;skip to next
inc bx ;odd number
cmp bx,max ;are we done?
jle search ;not yet
;print out total number of primes and return
mov bx,cx ;put count in BX
call binidec ;print it
ret ;return from program to DOS
main endp ;end of main part of program
binidec proc near
;subroutine to convert binary number in BX
; to decimal on console screen
push bx ;save BX
push cx ;save CX
;print three spaces
mov dx,offset mess2
mov ah,print_m
int doscall
;divide by successive powers of 10d
mov cx,100d
call dec_div
mov cx,10d
call dec_div
mov cx,1d
call dec_div
pop cx ;restore CX
pop bx ;restore BX
ret ;return from binidec
dec_div proc near
;sub-subroutine to divide number in BX by
;number in CX, print quotinet on screen
mov ax,bx ;put number in AX
cwd ;AX into AX and DX
div cx ;divide by CX
mov bx,dx ;remainder into BX
mov dl,al ;quotient into DL
;print the contents of DL on screen
add dl,30h ;convert to ASCII
mov ah,2h ;display char function
int doscall
ret
dec_div endp
binidec endp
pro_nam ends ;end of code segment
end start ;end assembly
|
Clarification of Answer by
studboy-ga
on
16 Apr 2005 15:08 PDT
Also, I don't quite understand when you said first program is *not* working?
It's printing out the primes fine, not just odd numbers.
My modified program should start from 100 (101) and on:
max equ 999d ;highest number
print_m equ 9h ;print message function
doscall equ 21h ;DOS interrupt number
datarea segment ;define data segment
numbers db max dup (?) ;buffer for integers
mess1 db 'calculting ....$'
mess2 db ' $' ;one space
datarea ends
pro_nam segment ;define code segment
main proc far ;main part of program
assume cs:pro_nam,ds:datarea
start: ;starting execution address
;set up stack for return
push ds ;save DS on stack
sub ax,ax ;set AX to zero
push ax ;put on stack
;set DS to data segment
mov ax,datarea
mov ds,ax
;print initial message
mov dx,offset mess1
mov ah,print_m
int doscall
mov dx,offset mess2
mov ah,print_m
int doscall
;set count of primes to zero (CX register)
mov cx,0 ;set CX to zero
;fill odd numbers in array with zero
mov bx,100 ;start at 100
fill_0:
mov [numbers + bx],0
inc bx
inc bx
cmp bx,max
jle fill_0
;find primes, cross out all the nonprimes
mov bx,3 ;start with 3
;has this number been flagged as a nonprime?
search:
mov al,[numbers + bx]
cmp al,1
je go_next
;no, so it's a prime
;the semicolon can be removed from the
;following line to print out the primes
call binidec ;print the prime
inc cx ;count the prime
;cross out all the numbers that are multiples
;of this prime, by marking them "1"
mov si,bx ;j=i
cross_out:
add si,bx ;j=j+i
cmp si,max ;gone too far yet?
jg go_next ;yes
mov [numbers + si],1
jmp cross_out
;have we looked at all the numbers?
go_next:
inc bx ;skip to next
inc bx ;odd number
cmp bx,max ;are we done?
jle search ;not yet
;print out total number of primes and return
mov bx,cx ;put count in BX
call binidec ;print it
ret ;return from program to DOS
main endp ;end of main part of program
binidec proc near
;subroutine to convert binary number in BX
; to decimal on console screen
push bx ;save BX
push cx ;save CX
;print three spaces
mov dx,offset mess2
mov ah,print_m
int doscall
;divide by successive powers of 10d
mov cx,100d
call dec_div
mov cx,10d
call dec_div
mov cx,1d
call dec_div
pop cx ;restore CX
pop bx ;restore BX
ret ;return from binidec
dec_div proc near
;sub-subroutine to divide number in BX by
;number in CX, print quotinet on screen
mov ax,bx ;put number in AX
cwd ;AX into AX and DX
div cx ;divide by CX
mov bx,dx ;remainder into BX
mov dl,al ;quotient into DL
;print the contents of DL on screen
add dl,30h ;convert to ASCII
mov ah,2h ;display char function
int doscall
ret
dec_div endp
binidec endp
pro_nam ends ;end of code segment
end start ;end assembly
|
Clarification of Answer by
studboy-ga
on
16 Apr 2005 15:09 PDT
Use this one--small typo in previous version:
max equ 999d ;highest number
print_m equ 9h ;print message function
doscall equ 21h ;DOS interrupt number
datarea segment ;define data segment
numbers db max dup (?) ;buffer for integers
mess1 db 'calculting ....$'
mess2 db ' $' ;one space
datarea ends
pro_nam segment ;define code segment
main proc far ;main part of program
assume cs:pro_nam,ds:datarea
start: ;starting execution address
;set up stack for return
push ds ;save DS on stack
sub ax,ax ;set AX to zero
push ax ;put on stack
;set DS to data segment
mov ax,datarea
mov ds,ax
;print initial message
mov dx,offset mess1
mov ah,print_m
int doscall
mov dx,offset mess2
mov ah,print_m
int doscall
;set count of primes to zero (CX register)
mov cx,0 ;set CX to zero
;fill odd numbers in array with zero
mov bx,100 ;start at 100
fill_0:
mov [numbers + bx],0
inc bx
inc bx
cmp bx,max
jle fill_0
;find primes, cross out all the nonprimes
mov bx,100 ;start with 100
;has this number been flagged as a nonprime?
search:
mov al,[numbers + bx]
cmp al,1
je go_next
;no, so it's a prime
;the semicolon can be removed from the
;following line to print out the primes
call binidec ;print the prime
inc cx ;count the prime
;cross out all the numbers that are multiples
;of this prime, by marking them "1"
mov si,bx ;j=i
cross_out:
add si,bx ;j=j+i
cmp si,max ;gone too far yet?
jg go_next ;yes
mov [numbers + si],1
jmp cross_out
;have we looked at all the numbers?
go_next:
inc bx ;skip to next
inc bx ;odd number
cmp bx,max ;are we done?
jle search ;not yet
;print out total number of primes and return
mov bx,cx ;put count in BX
call binidec ;print it
ret ;return from program to DOS
main endp ;end of main part of program
binidec proc near
;subroutine to convert binary number in BX
; to decimal on console screen
push bx ;save BX
push cx ;save CX
;print three spaces
mov dx,offset mess2
mov ah,print_m
int doscall
;divide by successive powers of 10d
mov cx,100d
call dec_div
mov cx,10d
call dec_div
mov cx,1d
call dec_div
pop cx ;restore CX
pop bx ;restore BX
ret ;return from binidec
dec_div proc near
;sub-subroutine to divide number in BX by
;number in CX, print quotinet on screen
mov ax,bx ;put number in AX
cwd ;AX into AX and DX
div cx ;divide by CX
mov bx,dx ;remainder into BX
mov dl,al ;quotient into DL
;print the contents of DL on screen
add dl,30h ;convert to ASCII
mov ah,2h ;display char function
int doscall
ret
dec_div endp
binidec endp
pro_nam ends ;end of code segment
end start ;end assembly
|
Request for Answer Clarification by
kffru-ga
on
16 Apr 2005 15:11 PDT
I don't have a place to post the package, but I think this way that may work.
I apply for a email, and then I send the package to the mail. I will
tell you the password. You can download from it.
Do you think this way is ok for you?
|
Clarification of Answer by
studboy-ga
on
16 Apr 2005 15:12 PDT
max equ 999d ;highest number
print_m equ 9h ;print message function
doscall equ 21h ;DOS interrupt number
datarea segment ;define data segment
numbers db max dup (?) ;buffer for integers
mess1 db 'calculting ....$'
mess2 db ' $' ;one space
datarea ends
pro_nam segment ;define code segment
main proc far ;main part of program
assume cs:pro_nam,ds:datarea
start: ;starting execution address
;set up stack for return
push ds ;save DS on stack
sub ax,ax ;set AX to zero
push ax ;put on stack
;set DS to data segment
mov ax,datarea
mov ds,ax
;print initial message
mov dx,offset mess1
mov ah,print_m
int doscall
mov dx,offset mess2
mov ah,print_m
int doscall
;set count of primes to zero (CX register)
mov cx,0 ;set CX to zero
;fill odd numbers in array with zero
mov bx,101 ;start at 101
fill_0:
mov [numbers + bx],0
inc bx
inc bx
cmp bx,max
jle fill_0
;find primes, cross out all the nonprimes
mov bx,101 ;start with 101
;has this number been flagged as a nonprime?
search:
mov al,[numbers + bx]
cmp al,1
je go_next
;no, so it's a prime
;the semicolon can be removed from the
;following line to print out the primes
call binidec ;print the prime
inc cx ;count the prime
;cross out all the numbers that are multiples
;of this prime, by marking them "1"
mov si,bx ;j=i
cross_out:
add si,bx ;j=j+i
cmp si,max ;gone too far yet?
jg go_next ;yes
mov [numbers + si],1
jmp cross_out
;have we looked at all the numbers?
go_next:
inc bx ;skip to next
inc bx ;odd number
cmp bx,max ;are we done?
jle search ;not yet
;print out total number of primes and return
mov bx,cx ;put count in BX
call binidec ;print it
ret ;return from program to DOS
main endp ;end of main part of program
binidec proc near
;subroutine to convert binary number in BX
; to decimal on console screen
push bx ;save BX
push cx ;save CX
;print three spaces
mov dx,offset mess2
mov ah,print_m
int doscall
;divide by successive powers of 10d
mov cx,100d
call dec_div
mov cx,10d
call dec_div
mov cx,1d
call dec_div
pop cx ;restore CX
pop bx ;restore BX
ret ;return from binidec
dec_div proc near
;sub-subroutine to divide number in BX by
;number in CX, print quotinet on screen
mov ax,bx ;put number in AX
cwd ;AX into AX and DX
div cx ;divide by CX
mov bx,dx ;remainder into BX
mov dl,al ;quotient into DL
;print the contents of DL on screen
add dl,30h ;convert to ASCII
mov ah,2h ;display char function
int doscall
ret
dec_div endp
binidec endp
pro_nam ends ;end of code segment
end start ;end assembly
|
Clarification of Answer by
studboy-ga
on
16 Apr 2005 15:13 PDT
Yes, we can try the email approach--
that way I can download the assembler instead of guessing at what you
try to do over there. BTW, try the latest one:
max equ 999d ;highest number
print_m equ 9h ;print message function
doscall equ 21h ;DOS interrupt number
datarea segment ;define data segment
numbers db max dup (?) ;buffer for integers
mess1 db 'calculting ....$'
mess2 db ' $' ;one space
datarea ends
pro_nam segment ;define code segment
main proc far ;main part of program
assume cs:pro_nam,ds:datarea
start: ;starting execution address
;set up stack for return
push ds ;save DS on stack
sub ax,ax ;set AX to zero
push ax ;put on stack
;set DS to data segment
mov ax,datarea
mov ds,ax
;print initial message
mov dx,offset mess1
mov ah,print_m
int doscall
mov dx,offset mess2
mov ah,print_m
int doscall
;set count of primes to zero (CX register)
mov cx,0 ;set CX to zero
;fill odd numbers in array with zero
mov bx,101 ;start at 101
fill_0:
mov [numbers + bx],0
inc bx
inc bx
cmp bx,max
jle fill_0
;find primes, cross out all the nonprimes
mov bx,101 ;start with 101
;has this number been flagged as a nonprime?
search:
mov al,[numbers + bx]
cmp al,1
je go_next
;no, so it's a prime
;the semicolon can be removed from the
;following line to print out the primes
call binidec ;print the prime
inc cx ;count the prime
;cross out all the numbers that are multiples
;of this prime, by marking them "1"
mov si,bx ;j=i
cross_out:
add si,bx ;j=j+i
cmp si,max ;gone too far yet?
jg go_next ;yes
mov [numbers + si],1
jmp cross_out
;have we looked at all the numbers?
go_next:
inc bx ;skip to next
inc bx ;odd number
cmp bx,max ;are we done?
jle search ;not yet
;print out total number of primes and return
mov bx,cx ;put count in BX
call binidec ;print it
ret ;return from program to DOS
main endp ;end of main part of program
binidec proc near
;subroutine to convert binary number in BX
; to decimal on console screen
push bx ;save BX
push cx ;save CX
;print three spaces
mov dx,offset mess2
mov ah,print_m
int doscall
;divide by successive powers of 10d
mov cx,100d
call dec_div
mov cx,10d
call dec_div
mov cx,1d
call dec_div
pop cx ;restore CX
pop bx ;restore BX
ret ;return from binidec
dec_div proc near
;sub-subroutine to divide number in BX by
;number in CX, print quotinet on screen
mov ax,bx ;put number in AX
cwd ;AX into AX and DX
div cx ;divide by CX
mov bx,dx ;remainder into BX
mov dl,al ;quotient into DL
;print the contents of DL on screen
add dl,30h ;convert to ASCII
mov ah,2h ;display char function
int doscall
ret
dec_div endp
binidec endp
pro_nam ends ;end of code segment
end start ;end assembly
|
Request for Answer Clarification by
kffru-ga
on
16 Apr 2005 15:15 PDT
I ran the program. This is the result
C:\TASM>tasm test
Turbo Assembler Version 1.0 Copyright (c) 1988 by Borland International
Assembling file: TEST.ASM
Error messages: None
Warning messages: None
Remaining memory: 488k
C:\TASM>tlink test
Turbo Link Version 2.0 Copyright (c) 1987, 1988 Borland International
Warning: no stack
C:\TASM>test
calculting .... 100 102 104 106 108 110 112 114 116 118 120 122 124 126 128 130
132 134 136 138 140 142 144 146 148 150 152 154 156 158 160 162 164 166 168 170
172 174 176 178 180 182 184 186 188 190 192 194 196 198 202 206 210 214 218 222
226 230 234 238 242 246 250 254 258 262 266 270 274 278 282 286 290 294 298 302
310 314 322 326 334 338 346 350 358 362 370 374 382 386 394 398 406 410 418 422
430 434 442 446 454 458 466 470 478 482 490 494 502 506 514 518 526 538 542 554
562 566 574 578 586 598 602 614 622 626 634 638 646 658 662 674 682 686 694 698
706 718 722 734 746 754 758 766 778 782 794 802 806 814 818 838 842 862 866 874
878 886 898 902 914 922 926 934 946 958 962 974 982 986 998 171
C:\TASM>
|
Request for Answer Clarification by
kffru-ga
on
16 Apr 2005 15:18 PDT
I try the last program. This is the result.
C:\TASM>tasm lastone
Turbo Assembler Version 1.0 Copyright (c) 1988 by Borland International
Assembling file: LASTONE.ASM
Error messages: None
Warning messages: None
Remaining memory: 488k
C:\TASM>tlink lastone
Turbo Link Version 2.0 Copyright (c) 1987, 1988 Borland International
Warning: no stack
C:\TASM>lastone
calculting .... 101 103 105 107 109 111 113 115 117 119 121 123 125 127 129 131
133 135 137 139 141 143 145 147 149 151 153 155 157 159 161 163 165 167 169 171
173 175 177 179 181 183 185 187 189 191 193 195 197 199 201 203 205 207 209 211
213 215 217 219 221 223 225 227 229 231 233 235 237 239 241 243 245 247 249 251
253 255 257 259 261 263 265 267 269 271 273 275 277 279 281 283 285 287 289 291
293 295 297 299 301 305 307 311 313 317 319 323 325 329 331 335 337 341 343 347
349 353 355 359 361 365 367 371 373 377 379 383 385 389 391 395 397 401 403 407
409 413 415 419 421 425 427 431 433 437 439 443 445 449 451 455 457 461 463 467
469 473 475 479 481 485 487 491 493 497 499 503 509 511 517 521 523 527 529 533
539 541 547 551 553 557 559 563 569 571 577 581 583 587 589 593 599 601 607 611
613 617 619 623 629 631 637 641 643 647 649 653 659 661 667 671 673 677 679 683
689 691 697 701 703 709 713 719 727 731 733 737 739 743 751 757 761 767 769 773
779 781 787 793 797 799 803 809 811 817 821 823 827 829 839 841 851 853 857 859
863 869 871 877 881 883 887 893 899 901 907 911 913 919 923 929 937 941 943 947
949 953 961 967 971 977 979 983 989 991 997 287
C:\TASM>
|
Clarification of Answer by
studboy-ga
on
16 Apr 2005 15:19 PDT
OK, we're getting close. I think you download my *previous*
program--not the latest. Try the latest:
max equ 999d ;highest number
print_m equ 9h ;print message function
doscall equ 21h ;DOS interrupt number
datarea segment ;define data segment
numbers db max dup (?) ;buffer for integers
mess1 db 'calculting ....$'
mess2 db ' $' ;one space
datarea ends
pro_nam segment ;define code segment
main proc far ;main part of program
assume cs:pro_nam,ds:datarea
start: ;starting execution address
;set up stack for return
push ds ;save DS on stack
sub ax,ax ;set AX to zero
push ax ;put on stack
;set DS to data segment
mov ax,datarea
mov ds,ax
;print initial message
mov dx,offset mess1
mov ah,print_m
int doscall
mov dx,offset mess2
mov ah,print_m
int doscall
;set count of primes to zero (CX register)
mov cx,0 ;set CX to zero
;fill odd numbers in array with zero
mov bx,101 ;start at 101
fill_0:
mov [numbers + bx],0
inc bx
inc bx
cmp bx,max
jle fill_0
;find primes, cross out all the nonprimes
mov bx,101 ;start with 101
;has this number been flagged as a nonprime?
search:
mov al,[numbers + bx]
cmp al,1
je go_next
;no, so it's a prime
;the semicolon can be removed from the
;following line to print out the primes
call binidec ;print the prime
inc cx ;count the prime
;cross out all the numbers that are multiples
;of this prime, by marking them "1"
mov si,bx ;j=i
cross_out:
add si,bx ;j=j+i
cmp si,max ;gone too far yet?
jg go_next ;yes
mov [numbers + si],1
jmp cross_out
;have we looked at all the numbers?
go_next:
inc bx ;skip to next
inc bx ;odd number
cmp bx,max ;are we done?
jle search ;not yet
;print out total number of primes and return
mov bx,cx ;put count in BX
call binidec ;print it
ret ;return from program to DOS
main endp ;end of main part of program
binidec proc near
;subroutine to convert binary number in BX
; to decimal on console screen
push bx ;save BX
push cx ;save CX
;print three spaces
mov dx,offset mess2
mov ah,print_m
int doscall
;divide by successive powers of 10d
mov cx,100d
call dec_div
mov cx,10d
call dec_div
mov cx,1d
call dec_div
pop cx ;restore CX
pop bx ;restore BX
ret ;return from binidec
dec_div proc near
;sub-subroutine to divide number in BX by
;number in CX, print quotinet on screen
mov ax,bx ;put number in AX
cwd ;AX into AX and DX
div cx ;divide by CX
mov bx,dx ;remainder into BX
mov dl,al ;quotient into DL
;print the contents of DL on screen
add dl,30h ;convert to ASCII
mov ah,2h ;display char function
int doscall
ret
dec_div endp
binidec endp
pro_nam ends ;end of code segment
end start ;end assembly
|
Clarification of Answer by
studboy-ga
on
16 Apr 2005 15:21 PDT
OK, we are getting closer. Can you give me sometime to debug it a bit?
I think we can get this done.
|
Clarification of Answer by
studboy-ga
on
16 Apr 2005 15:33 PDT
OK, I found the bug. try this:
max equ 999d ;highest number
print_m equ 9h ;print message function
doscall equ 21h ;DOS interrupt number
datarea segment ;define data segment
numbers db max dup (?) ;buffer for integers
mess1 db 'calculting ....$'
mess2 db ' $' ;one space
datarea ends
pro_nam segment ;define code segment
main proc far ;main part of program
assume cs:pro_nam,ds:datarea
start: ;starting execution address
;set up stack for return
push ds ;save DS on stack
sub ax,ax ;set AX to zero
push ax ;put on stack
;set DS to data segment
mov ax,datarea
mov ds,ax
;print initial message
mov dx,offset mess1
mov ah,print_m
int doscall
mov dx,offset mess2
mov ah,print_m
int doscall
;set count of primes to zero (CX register)
mov cx,0 ;set CX to zero
;fill odd numbers in array with zero
mov bx,3 ;start at 3
fill_0:
mov [numbers + bx],0
cmp bx,100
jge skip
mov [numbers + bx],1
skip:
inc bx
inc bx
cmp bx,max
jle fill_0
;find primes, cross out all the nonprimes
mov bx,3 ;start with 3
;has this number been flagged as a nonprime?
search:
mov al,[numbers + bx]
cmp al,1
je go_next
;no, so it's a prime
;the semicolon can be removed from the
;following line to print out the primes
call binidec ;print the prime
inc cx ;count the prime
;cross out all the numbers that are multiples
;of this prime, by marking them "1"
mov si,bx ;j=i
cross_out:
add si,bx ;j=j+i
cmp si,max ;gone too far yet?
jg go_next ;yes
mov [numbers + si],1
jmp cross_out
;have we looked at all the numbers?
go_next:
inc bx ;skip to next
inc bx ;odd number
cmp bx,max ;are we done?
jle search ;not yet
;print out total number of primes and return
mov bx,cx ;put count in BX
call binidec ;print it
ret ;return from program to DOS
main endp ;end of main part of program
binidec proc near
;subroutine to convert binary number in BX
; to decimal on console screen
push bx ;save BX
push cx ;save CX
;print three spaces
mov dx,offset mess2
mov ah,print_m
int doscall
;divide by successive powers of 10d
mov cx,100d
call dec_div
mov cx,10d
call dec_div
mov cx,1d
call dec_div
pop cx ;restore CX
pop bx ;restore BX
ret ;return from binidec
dec_div proc near
;sub-subroutine to divide number in BX by
;number in CX, print quotinet on screen
mov ax,bx ;put number in AX
cwd ;AX into AX and DX
div cx ;divide by CX
mov bx,dx ;remainder into BX
mov dl,al ;quotient into DL
;print the contents of DL on screen
add dl,30h ;convert to ASCII
mov ah,2h ;display char function
int doscall
ret
dec_div endp
binidec endp
pro_nam ends ;end of code segment
end start ;end assembly
|
Clarification of Answer by
studboy-ga
on
16 Apr 2005 15:42 PDT
max equ 999d ;highest number
print_m equ 9h ;print message function
doscall equ 21h ;DOS interrupt number
datarea segment ;define data segment
numbers db max dup (?) ;buffer for integers
mess1 db 'calculating ....$'
mess2 db ' $' ;one space
datarea ends
pro_nam segment ;define code segment
main proc far ;main part of program
assume cs:pro_nam,ds:datarea
start: ;starting execution address
;set up stack for return
push ds ;save DS on stack
sub ax,ax ;set AX to zero
push ax ;put on stack
;set DS to data segment
mov ax,datarea
mov ds,ax
;print initial message
mov dx,offset mess1
mov ah,print_m
int doscall
mov dx,offset mess2
mov ah,print_m
int doscall
;set count of primes to zero (CX register)
mov cx,0 ;set CX to zero
;fill odd numbers in array with zero
mov bx,3 ;start at 3
fill_0:
mov [numbers + bx],0
cmp bx,100
jge skip
mov [numbers + bx],1
skip:
inc bx
inc bx
cmp bx,max
jle fill_0
;find primes, cross out all the nonprimes
mov bx,3 ;start with 3
;has this number been flagged as a nonprime?
search:
mov al,[numbers + bx]
cmp al,1
je go_next
;no, so it's a prime
;the semicolon can be removed from the
;following line to print out the primes
call binidec ;print the prime
inc cx ;count the prime
;cross out all the numbers that are multiples
;of this prime, by marking them "1"
mov si,bx ;j=i
cross_out:
add si,bx ;j=j+i
cmp si,max ;gone too far yet?
jg go_next ;yes
mov [numbers + si],1
jmp cross_out
;have we looked at all the numbers?
go_next:
inc bx ;skip to next
inc bx ;odd number
cmp bx,max ;are we done?
jle search ;not yet
;print out total number of primes and return
mov bx,cx ;put count in BX
call binidec ;print it
ret ;return from program to DOS
main endp ;end of main part of program
binidec proc near
;subroutine to convert binary number in BX
; to decimal on console screen
push bx ;save BX
push cx ;save CX
;print three spaces
mov dx,offset mess2
mov ah,print_m
int doscall
;divide by successive powers of 10d
mov cx,100d
call dec_div
mov cx,10d
call dec_div
mov cx,1d
call dec_div
pop cx ;restore CX
pop bx ;restore BX
ret ;return from binidec
dec_div proc near
;sub-subroutine to divide number in BX by
;number in CX, print quotinet on screen
mov ax,bx ;put number in AX
cwd ;AX into AX and DX
div cx ;divide by CX
mov bx,dx ;remainder into BX
mov dl,al ;quotient into DL
;print the contents of DL on screen
add dl,30h ;convert to ASCII
mov ah,2h ;display char function
int doscall
ret
dec_div endp
binidec endp
pro_nam ends ;end of code segment
end start ;end assembly
|
Request for Answer Clarification by
kffru-ga
on
16 Apr 2005 16:06 PDT
I try this program which the time is 15:42 PDT. this the result
Turbo Assembler Version 1.0 Copyright (c) 1988 by Borland International
Assembling file: TEST.ASM
Error messages: None
Warning messages: None
Remaining memory: 488k
C:\TASM>tlink test
Turbo Link Version 2.0 Copyright (c) 1987, 1988 Borland International
Warning: no stack
C:\TASM>test
calculating .... 101 103 105 107 109 111 113 115 117 119 121 123 125 127 129 13
1 133 135 137 139 141 143 145 147 149 151 153 155 157 159 161 163 165 167 169 17
1 173 175 177 179 181 183 185 187 189 191 193 195 197 199 201 203 205 207 209 21
1 213 215 217 219 221 223 225 227 229 231 233 235 237 239 241 243 245 247 249 25
1 253 255 257 259 261 263 265 267 269 271 273 275 277 279 281 283 285 287 289 29
1 293 295 297 299 301 305 307 311 313 317 319 323 325 329 331 335 337 341 343 34
7 349 353 355 359 361 365 367 371 373 377 379 383 385 389 391 395 397 401 403 40
7 409 413 415 419 421 425 427 431 433 437 439 443 445 449 451 455 457 461 463 46
7 469 473 475 479 481 485 487 491 493 497 499 503 509 511 517 521 523 527 529 53
3 539 541 547 551 553 557 559 563 569 571 577 581 583 587 589 593 599 601 607 61
1 613 617 619 623 629 631 637 641 643 647 649 653 659 661 667 671 673 677 679 68
3 689 691 697 701 703 709 713 719 727 731 733 737 739 743 751 757 761 767 769 77
3 779 781 787 793 797 799 803 809 811 817 821 823 827 829 839 841 851 853 857 85
9 863 869 871 877 881 883 887 893 899 901 907 911 913 919 923 929 937 941 943 94
7 949 953 961 967 971 977 979 983 989 991 997 287
why does it appear the last number 287 and need to modify the last column
--------------------------------------------------------------------------
the mail: kffre2005@yahoo.com
password: abc123
you can download the package1 and package2
I wonder you will use my first program or second program, because I
don't think my first program is correct.
thank you
|
Request for Answer Clarification by
kffru-ga
on
16 Apr 2005 16:40 PDT
I ran the last program(the time is 15:42 PDT), and then you can see
the 105, 115 and so on. They are not prime numbers, because I think my
algorithm of first program is not right. How do you think?
|
Clarification of Answer by
studboy-ga
on
16 Apr 2005 16:41 PDT
The last column is because of your screen width--every wraps around.
The last number 287 is the number of primes.
Both first and second programs are very close to being correct,
although both are incorrect.
Personally I like your first program better because it looks more
original. The second program looks like it's takem from somewhere
from the web. Since we still have 4 days, let's spend some time
fixing up the first program, or try to merge the two, rather then just
use the second straight without any understanding.
Can you open a gmail email acct and up load the tasm assembler for me? Thanks.
|
Clarification of Answer by
studboy-ga
on
16 Apr 2005 16:42 PDT
Also may I ask the origins of these programs. Thanks.
|
Clarification of Answer by
studboy-ga
on
16 Apr 2005 16:46 PDT
I'm downloading tasm from your yahoo mail...
|
Request for Answer Clarification by
kffru-ga
on
16 Apr 2005 17:02 PDT
these are origins
-------------------------first program---------------------------
max equ 16381d ;highest number
display equ 2h ;display char function
print_m equ 9h ;print message function
doscall equ 21h ;DOS interrupt number
;*********************************************
datarea segment ;define data segment
numbers db max dup (?) ;buffer for integers
mess1 db 'calculting ....$'
mess2 db ' $' ;three spaces
datarea ends
;*********************************************
pro_nam segment ;define code segment
;---------------------------------------------
main proc far ;main part of program
assume cs:pro_nam,ds:datarea
start: ;starting execution address
;set up stack for return
push ds ;save DS on stack
sub ax,ax ;set AX to zero
push ax ;put on stack
;set DS to data segment
mov ax,datarea
mov ds,ax
;print initial message
mov dx,offset mess1
mov ah,print_m
int doscall
;set count of primes to zero (CX register)
mov cx,0 ;set CX to zero
;fill odd numbers in array with zero
mov bx,3 ;start at 3
fill_0:
mov [numbers + bx],0
inc bx
inc bx
cmp bx,max
jle fill_0
;find primes, cross out all the nonprimes
mov bx,3 ;start with 3
;has this number been flagged as a nonprime?
search:
mov al,[numbers + bx]
cmp al,1
je go_next
;no, so it's a prime
;the semicolon can be removed from the
;following line to print out the primes
call binidec ;print the prime
inc cx ;count the prime
;cross out all the numbers that are multiples
; of this prime, by marking them "1"
mov si,bx ;j=i
cross_out:
add si,bx ;j=j+i
cmp si,max ;gone too far yet?
jg go_next ;yes
mov [numbers + si],1
jmp cross_out
;have we looked at all the numbers?
go_next:
inc bx ;skip to next
inc bx ; odd number
cmp bx,max ;are we done?
jle search ;not yet
;print out total number of primes and return
mov bx,cx ;put count in BX
call binidec ;print it
ret ;return from program to DOS
main endp ;end of main part of program
;---------------------------------------------
binidec proc near
;subroutine to convert binary number in BX
; to decimal on console screen
push bx ;save BX
push cx ;save CX
;print three spaces
mov dx,offset mess2
mov ah,print_m
int doscall
;divide by successive powers of 10d
mov cx,10000d
call dec_div
mov cx,1000d
call dec_div
mov cx,100d
call dec_div
mov cx,10d
call dec_div
mov cx,1d
call dec_div
pop cx ;restore CX
pop bx ;restore BX
ret ;return from binidec
;- - - - - - - - - - - - - - - - - - - - - - -
dec_div proc near
;sub-subroutine to divide number in BX by
; number in CX, print quotinet on screen
mov ax,bx ;put number in AX
cwd ;AX into AX and DX
div cx ;divide by CX
mov bx,dx ;remainder into BX
mov dl,al ;quotient into DL
;print the contents of DL on screen
add dl,30h ;convert to ASCII
mov ah,display
int doscall
ret
dec_div endp
;- - - - - - - - - - - - - - - - - - - - - - -
binidec endp
;---------------------------------------------
pro_nam ends ;end of code segment
;*********************************************
end start ;end assembly
I fixed the second program before I posted it, because the origin had
some error and warning messages. now, it is down for maintenance. I
can't find it.
|
Clarification of Answer by
studboy-ga
on
16 Apr 2005 17:09 PDT
OK, it's debugged. Please try this one:
max equ 999d ;highest number
print_m equ 9h ;print message function
doscall equ 21h ;DOS interrupt number
datarea segment ;define data segment
numbers db max dup (?) ;buffer for integers
mess1 db 'calculating ....$'
mess2 db ' $' ;three spaces
datarea ends
pro_nam segment ;define code segment
main proc far ;main part of program
assume cs:pro_nam,ds:datarea
start: ;starting execution address
;set up stack for return
push ds ;save DS on stack
sub ax,ax ;set AX to zero
push ax ;put on stack
;set DS to data segment
mov ax,datarea
mov ds,ax
;print initial message
mov dx,offset mess1
mov ah,print_m
int doscall
mov dx,offset mess2
mov ah,print_m
int doscall
;set count of primes to zero (CX register)
mov cx,0 ;set CX to zero
;fill odd numbers in array with zero
mov bx,3 ;start at 3
fill_0:
mov [numbers + bx],0
inc bx
inc bx
cmp bx,max
jle fill_0
;find primes, cross out all the nonprimes
mov bx,3 ;start with 3
;has this number been flagged as a nonprime?
search:
mov al,[numbers + bx]
cmp al,1
je go_next
;no, so it's a prime
cmp bx,100
jle skip
;the semicolon can be removed from the
;following line to print out the primes
call binidec ;print the prime
inc cx ;count the prime
skip:
;cross out all the numbers that are multiples
;of this prime, by marking them "1"
mov si,bx ;j=i
cross_out:
add si,bx ;j=j+i
cmp si,max ;gone too far yet?
jg go_next ;yes
mov [numbers + si],1
jmp cross_out
;have we looked at all the numbers?
go_next:
inc bx ;skip to next
inc bx ;odd number
cmp bx,max ;are we done?
jle search ;not yet
;print out total number of primes and return
mov bx,cx ;put count in BX
call binidec ;print it
ret ;return from program to DOS
main endp ;end of main part of program
binidec proc near
;subroutine to convert binary number in BX
; to decimal on console screen
push bx ;save BX
push cx ;save CX
;print three spaces
mov dx,offset mess2
mov ah,print_m
int doscall
;divide by successive powers of 10d
mov cx,100d
call dec_div
mov cx,10d
call dec_div
mov cx,1d
call dec_div
pop cx ;restore CX
pop bx ;restore BX
ret ;return from binidec
dec_div proc near
;sub-subroutine to divide number in BX by
;number in CX, print quotient on screen
mov ax,bx ;put number in AX
cwd ;AX into AX and DX
div cx ;divide by CX
mov bx,dx ;remainder into BX
mov dl,al ;quotient into DL
;print the contents of DL on screen
add dl,30h ;convert to ASCII
mov ah,2h ;display char function
int doscall
ret
dec_div endp
binidec endp
pro_nam ends ;end of code segment
end start ;end assembly
|
Clarification of Answer by
studboy-ga
on
16 Apr 2005 17:10 PDT
My TASM output:
M:\tasm>try
calculating .... 101 103 107 109 113 127 131 137 139 149 151 157
163 167 173 179 181 191 193 197 199 211 223 227 229 233 239 241
251 257 263 269 271 277 281 283 293 307 311 313 317 331 337 347
349 353 359 367 373 379 383 389 397 401 409 419 421 431 433 439
443 449 457 461 463 467 479 487 491 499 503 509 521 523 541 547
557 563 569 571 577 587 593 599 601 607 613 617 619 631 641 643
647 653 659 661 673 677 683 691 701 709 719 727 733 739 743 751
757 761 769 773 787 797 809 811 821 823 827 829 839 853 857 859
863 877 881 883 887 907 911 919 929 937 941 947 953 967 971 977
983 991 997 143
|
Clarification of Answer by
studboy-ga
on
16 Apr 2005 17:13 PDT
Again, the 143 at the end is the total number of primes. If you don't
want it, you can comment it out in the program.
What I meant by origin is from where did you find it from? :) Just kidding.
Well, anyway, just to let you know, the second one is *definitely*
taken from the web (I found it). If this is an assignment, I would
recommend not using the second one. Also, if you plan to turn this in
as an assignment, please change the program per your understanding
(note that Google Answers is searchable and accessible to all).
|
Clarification of Answer by
studboy-ga
on
16 Apr 2005 17:21 PDT
max equ 999d ;highest number
print_m equ 9h ;print message function
doscall equ 21h ;DOS interrupt number
datarea segment ;define data segment
numbers db max dup (?) ;buffer for integers
mess1 db 'calculating....$'
mess2 db ' $' ;two spaces
datarea ends
pro_nam segment ;define code segment
main proc far ;main part of program
assume cs:pro_nam,ds:datarea
start: ;starting execution address
;set up stack for return
push ds ;save DS on stack
sub ax,ax ;set AX to zero
push ax ;put on stack
;set DS to data segment
mov ax,datarea
mov ds,ax
;print initial message
mov dx,offset mess1
mov ah,print_m
int doscall
mov dx,offset mess2
mov ah,print_m
int doscall
;set count of primes to zero (CX register)
mov cx,0 ;set CX to zero
;fill odd numbers in array with zero
mov bx,3 ;start at 3
fill_0:
mov [numbers + bx],0
inc bx
inc bx
cmp bx,max
jle fill_0
;find primes, cross out all the nonprimes
mov bx,3 ;start with 3
;has this number been flagged as a nonprime?
search:
mov al,[numbers + bx]
cmp al,1
je go_next
;no, so it's a prime
cmp bx,100
jle skip
;the semicolon can be removed from the
;following line to print out the primes
call binidec ;print the prime
inc cx ;count the prime
skip:
;cross out all the numbers that are multiples
;of this prime, by marking them "1"
mov si,bx ;j=i
cross_out:
add si,bx ;j=j+i
cmp si,max ;gone too far yet?
jg go_next ;yes
mov [numbers + si],1
jmp cross_out
;have we looked at all the numbers?
go_next:
inc bx ;skip to next
inc bx ;odd number
cmp bx,max ;are we done?
jle search ;not yet
;print out total number of primes and return
mov bx,cx ;put count in BX
call binidec ;print it
ret ;return from program to DOS
main endp ;end of main part of program
binidec proc near
;subroutine to convert binary number in BX
; to decimal on console screen
push bx ;save BX
push cx ;save CX
;print three spaces
mov dx,offset mess2
mov ah,print_m
int doscall
;divide by successive powers of 10d
mov cx,100d
call dec_div
mov cx,10d
call dec_div
mov cx,1d
call dec_div
pop cx ;restore CX
pop bx ;restore BX
ret ;return from binidec
dec_div proc near
;sub-subroutine to divide number in BX by
;number in CX, print quotient on screen
mov ax,bx ;put number in AX
cwd ;AX into AX and DX
div cx ;divide by CX
mov bx,dx ;remainder into BX
mov dl,al ;quotient into DL
;print the contents of DL on screen
add dl,30h ;convert to ASCII
mov ah,2h ;display char function
int doscall
ret
dec_div endp
binidec endp
pro_nam ends ;end of code segment
end start ;end assembly
|
Request for Answer Clarification by
kffru-ga
on
16 Apr 2005 17:36 PDT
Turbo Link Version 2.0 Copyright (c) 1987, 1988 Borland International
Warning: no stack
why does it show Warning: no stack?
|
Clarification of Answer by
studboy-ga
on
16 Apr 2005 17:42 PDT
Because we don't utilize the stack (push-pop) in our program -- we
don't need it. Not all programs have stacks.
|
Clarification of Answer by
studboy-ga
on
16 Apr 2005 17:53 PDT
Link to second program on web:
http://64.233.167.104/search?q=cache:ox8wY8jhWY0J:www.erikburrows.com/index.php%3Fnode%3DProgramming%2BLanguages+FoundPrime:&hl=en
|
Request for Answer Clarification by
kffru-ga
on
16 Apr 2005 18:35 PDT
How about first program? :)
anyway, thanks a lot
|
Clarification of Answer by
studboy-ga
on
16 Apr 2005 22:49 PDT
So far I cannot find the first program on the web--yet :)
So I think you're pretty safe with the first program =)
|
Request for Answer Clarification by
kffru-ga
on
17 Apr 2005 13:23 PDT
Because it comes from my note and my mind
If I don't want to see this "Warning: no stack", when I compile it, how should I do?
|
Clarification of Answer by
studboy-ga
on
17 Apr 2005 20:57 PDT
Well, maybe add a stack. Common sense isn't it? :) Le sens commun
n'est pas si commun... (Voltaire)
max equ 999d ;highest number
print_m equ 9h ;print message function
doscall equ 21h ;DOS interrupt number
.model small
.stack
.data
datarea segment ;define data segment
numbers db max dup (?) ;buffer for integers
mess1 db 'calculating....$'
mess2 db ' $' ;one space
datarea ends
.code
pro_nam segment ;define code segment
assume cs:pro_nam,ds:datarea
main proc far ;main part of program
start: ;starting execution address
;set up stack for return
push ds ;save DS on stack
sub ax,ax ;set AX to zero
push ax ;put on stack
;set DS to data segment
mov ax,datarea
mov ds,ax
;print initial message
mov dx,offset mess1
mov ah,print_m
int doscall
mov dx,offset mess2
mov ah,print_m
int doscall
;set count of primes to zero (CX register)
mov cx,0 ;set CX to zero
;fill odd numbers in array with zero
mov bx,3 ;start at 3
fill_0:
mov [numbers + bx],0
inc bx
inc bx
cmp bx,max
jle fill_0
;find primes, cross out all the nonprimes
mov bx,3 ;start with 3
;has this number been flagged as a nonprime?
search:
mov al,[numbers + bx]
cmp al,1
je go_next
;no, so it's a prime
cmp bx,100
jle skip
;the semicolon can be removed from the
;following line to print out the primes
call binidec ;print the prime
inc cx ;count the prime
skip:
;cross out all the numbers that are multiples
;of this prime, by marking them "1"
mov si,bx ;j=i
cross_out:
add si,bx ;j=j+i
cmp si,max ;gone too far yet?
jg go_next ;yes
mov [numbers + si],1
jmp cross_out
;have we looked at all the numbers?
go_next:
inc bx ;skip to next
inc bx ;odd number
cmp bx,max ;are we done?
jle search ;not yet
;print out total number of primes and return
mov bx,cx ;put count in BX
call binidec ;print it
ret ;return from program to DOS
main endp ;end of main part of program
binidec proc near
;subroutine to convert binary number in BX
; to decimal on console screen
push bx ;save BX
push cx ;save CX
;print three spaces
mov dx,offset mess2
mov ah,print_m
int doscall
;divide by successive powers of 10d
mov cx,100d
call dec_div
mov cx,10d
call dec_div
mov cx,1d
call dec_div
pop cx ;restore CX
pop bx ;restore BX
ret ;return from binidec
dec_div proc near
;sub-subroutine to divide number in BX by
;number in CX, print quotient on screen
mov ax,bx ;put number in AX
cwd ;AX into AX and DX
div cx ;divide by CX
mov bx,dx ;remainder into BX
mov dl,al ;quotient into DL
;print the contents of DL on screen
add dl,30h ;convert to ASCII
mov ah,2h ;display char function
int doscall
ret
dec_div endp
binidec endp
pro_nam ends ;end of code segment
end start ;end assembly
|