16位masm汇编实现筛法,状压求十万以内素数

.model small
.data
	table byte 3,12500 dup (0);;0和1不是质数
	i word 0
	j word 0

.stack 4096

.code
main proc far
start:
	mov ax,@data
	mov ds,ax
	mov di,offset table
	mov i,2
	mov cx,350
	s0:
		mov ax,i
		mov dx,0										;dx:ax/bx=ax...dx
		
		mov bx,8
		div bx
		push cx
			mov cx,dx									;余数 位移
			mov si,ax									;商   偏移地址
			mov dx,1
			shl dl,cl									;移位
			mov bx,di
			test [bx][si],dl								;noprime[i]
			jnz s0continue									;不是质数
		pop cx

		push cx
		mov ax,i
		mov j,ax											;j=i;i*j<=10w;j++
		s1:
			mov ax,j
			mul i
			and dx,dx
			jz setbit								;dx非零,若乘积大于等于65536,要跳过去特判,大于10w要跳出s1

			;dx>=1
			cmp dx,1								;等于1、大于1
			ja s0continue							;dx大于1要continue s0.等于要特判ax是否满足
			cmp ax,1000011010100000B
			ja s0continue							;ax大于阈值,continue s0

			setbit:
				mov bx,8
				div bx
				mov cx,dx
				mov si,ax
				mov bx,di
				mov dl,1
				shl dl,cl
				or [bx][si],dl
			inc j
		jmp s1
		s0continue:
		inc i
		pop cx
	loop s0
	
	mov cx,65533
	mov i,2
	output:
		mov dx,0
		mov ax,i
		mov bx,8
		div bx

		mov si,ax
		mov bx,di

		push cx
			mov cl,dl
			mov dl,1
			shl dl,cl
			test [bx][si],dl
			jnz outputconti
			mov dx,0
			mov ax,i
			call print16b_dec
		outputconti:
		pop cx
		inc i
	loop output

	mov cx,34464
	mov i,0
	output2:
		mov dx,1
		mov ax,i
		mov bx,8
		div bx

		mov si,ax
		mov bx,di

		push cx
			mov cl,dl
			mov dl,1
			shl dl,cl
			test [bx][si],dl
			jnz output2conti
			mov dx,1
			mov ax,i
			call print16b_dec
		output2conti:
		pop cx
		inc i
	loop output2
	
	mov ax,4c00h
	int 21h
main endp

print16b_dec proc near;用%d输出16bit,参数放在dx:ax,dx有0和1两种情况
	mov bx,10000D	;dx:ax/bx=ax...dx
	div bx
	mov bx,dx		;余数
	call print1dec
	mov ax,bx
	mov dx,0
	mov bx,1000D
	div bx
	mov bx,dx
	call print1dec
	mov ax,bx
	mov dx,0
	mov bx,100D
	div bx
	mov bx,dx
	call print1dec
	mov ax,bx
	mov dx,0
	mov bx,10D
	div bx
	mov bx,dx
	call print1dec
	mov ax,bx
	call print1dec
	mov dl,0dh
	mov ah,2h
	int 21h
	mov dl,0ah
	mov ah,2h
	int 21h
	ret
print16b_dec endp

printbig_dec proc near;用%d输出一个16bit数加上65536,参数放在ax

	mov dx,1
	mov bx,10000D	;dx:ax/bx=ax...dx
	div bx
	mov bx,dx		;余数
	call print1dec
	mov ax,bx
	mov dx,0
	mov bx,1000D
	div bx
	mov bx,dx
	call print1dec
	mov ax,bx
	mov dx,0
	mov bx,100D
	div bx
	mov bx,dx
	call print1dec
	mov ax,bx
	mov dx,0
	mov bx,10D
	div bx
	mov bx,dx
	call print1dec
	mov ax,bx
	call print1dec
	mov dl,0dh
	mov ah,2h
	int 21h
	mov dl,0ah
	mov ah,2h
	int 21h

printbig_dec endp

print1dec proc near;用来%d输出一个10进制位,参数放在ax
	mov dx,ax
	add dl,30h
	mov ah,2h
	int 21h
	ret
print1dec endp

end start

运行环境masm6.11
复杂度大概是\(O(n\log n)\)

posted @ 2019-11-21 22:09  wawcac  阅读(253)  评论(0编辑  收藏  举报