# 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
end start