要求
求 100 以内的素数。(1)用筛法求出这些素数。(2)在屏幕上显示出求素数的动态过程(在屏幕上先显示出 100 以内的所有数, 再动态地删去不符合要求的数,删除的过程要明显)。(3)计算这些素数的平均值(取整,四舍五入),以十进制形式输出,并让该值以红色显示。(4)数据的输入和结果的输出都要有必要的提示,且提示独占一行。(5)要使用到子程序。
终极代码
DATAS SEGMENT
sum dw ? ; sum of the primes
temp db ? ; record what to print now
vis db 110 dup(00h) ; mark prime
prime db 110 dup(00h) ; record prime
outsum db 00h ; 1red or 0normal
cnt dw 0000h ; curent number of primes
cursec db ? ; curent second
curmin db ? ; curent minute
curhou db ? ; curent hour
fl db ? ; if there's something deleted
DATAS ENDS
STACKS SEGMENT
STACKS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
mov ax, datas
mov ds, ax
mov ax, 0b800h
mov es, ax ; 保存显存的段地址
mov si, 0000H ; 数据段偏移地址
mov di, 21*160 ; 显存偏移地址
call MAIN
MAIN proc near
XOR bx,bx
XOR ax,ax
mov sum,BX
mov BL, 2 ; save i(that is the dividend)
ISPRIME:
mov di,21*160
mov cx,02h
PRINTREST: ; print all the numbers remain on the possible list
cmp cx,100
ja PRINTSPACE
mov si,cx
cmp vis[si],0
jne NOTPRIME
mov ax,si
call PRINTNUMBER
NOTPRIME:
inc cx
jmp PRINTREST
PRINTSPACE:
mov temp,' '
call OUTNORM
cmp di,25*160
je MAINPART
jmp PRINTSPACE
MAINPART:
cmp BL,100 ; check if need to end the program
je STOP ; end the program
mov fl,0 ; flag of delete something
mov si,bx
cmp vis[si],00h
jne OULER
mov si,cnt
mov prime[si],BL ; BL is a prime
inc cnt
add sum,bx
OULER:
mov cx,0 ; count primes
OULERLOOP: ; Ouler's marking
cmp cx,cnt
jae BREAKOULER ; cx>=cnt break
mov si,cx
mov al,prime[si]
mul bl
cmp ax,100
ja BREAKOULER ; bl*prime[cx]>n break
mov si,ax
mov vis[si],01h ; mark not prime
mov fl,01h ; flag=1,deleted something
xor ax,ax
mov al,bl
mov si,cx
div prime[si]
cmp ah,00h
je BREAKOULER ; bl%prime[cx]==0
inc cx
jmp OULERLOOP
STOP:
jmp STOPP ; the true code is too far
BREAKOULER:
inc BL
cmp fl,0
je WAKE ; nothing deleted,will not sleep
; push ax
; push cx
; push dx
mov ah,2ch
int 21h
mov cursec,dh
mov curmin,cl
mov curhou,ch
SLEEP:
mov ah,2ch
int 21h
cmp dh,cursec
ja WAKE
cmp cl,curmin
ja WAKE
cmp ch,curhou
ja WAKE
jmp SLEEP
WAKE:
; pop dx
; pop cx
; pop ax
jmp ISPRIME
STOPP:
mov di,22*160 ; println
call PRINTSTR
mov di,23*160
mov outsum,01h
mov AX,sum
call PRINTNUMBER
mov ah,01h
int 21h
MOV ah,4CH
int 21H
ret
MAIN endp
OUTNORM proc near
push ax
mov al,temp
cmp outsum,01h
je RED
mov ah,00000111B
jmp continue
RED:
mov ah,00100100B
continue:
mov es:[di],ax
add di,02h
pop ax
ret
OUTNORM endp
PRINTSTR proc near ; print'sum'
push ax
push bx
push cx
push dx
XOR dx,dx
XOR ax,ax
mov dl,'s'
mov temp,dl
call OUTNORM
;mov ah,2
;int 21h
mov dl,'u'
mov temp,dl
call OUTNORM
;mov ah,2
;int 21h
mov dl,'m'
mov temp,dl
call OUTNORM
;mov ah,2
;int 21h
pop dx
pop cx
pop bx
pop ax
ret
PRINTSTR endp
PRINTNUMBER proc near
push ax
push bx
push cx
push dx
mov bx,10
mov cx,0
PUSHTOSTACK:
mov dx,0
div bx
push dx
inc cx
cmp ax,0
jz POPFROMSTACK
jmp PUSHTOSTACK
POPFROMSTACK:
pop dx
add dl,30h ; change ASCII to real number
mov temp,dl
call OUTNORM
;mov ah,2
;int 21h
loop POPFROMSTACK
pop dx
pop cx
pop bx
pop ax
mov temp,' ' ; print an empty space
call OUTNORM
;mov AH,2
;mov DL,0
;int 21h
ret
PRINTNUMBER endp
CODES ENDS
END START

本文详细介绍了一种高效的素数筛选算法——动态欧拉筛的实现过程。通过子程序的调用,算法不仅展示了100以内素数的求解,还实现了动态删除非素数的可视化效果。代码中包含了素数的平均值计算及特殊颜色输出,充分体现了算法的实用性和趣味性。

被折叠的 条评论
为什么被折叠?



