为什么一直显示非零返回
计算素数个数程序。
使用Eratosthenes筛法,求1~100 000之间有多少个素数。
创建一个字节数组,以如下方法将不是素数的位置标记出来:2是一个素数,从位置2开始,把所有2的倍数的位置标记为1;2之后的素数3,将3的倍数的位置标记为1;3之后的素数是5,将5的倍数的位置标记为1;如此重复,直到标记所有非素数的位置,处理结束。数组中没有被标记的位置都对应一个素数。
将该数组实现定义在数据段.bss, 可以定义无初始化数据段,在.bss段中的数据不能有初值,在程序执行时才被分配存储空间。可以利用一段循环程序将初值0全部填入。
section .bss
numbers resb 100000 ; 创建一个大小为100000的字节数组
section .data
output_format db "%u",10,0 ; 输出格式字符串
section .text
extern printf
global main
main:
mov ecx, 100000 ; 初始化计数器为100000
xor edi, edi ; 清空edi寄存器,用于存储素数的个数
mov al, 1 ; al寄存器存储标记值1
init: ; 将数组所有元素初始化为0
dec ecx
xor bl, bl ; 清空bl寄存器
mov [numbers + ecx], bl
jnz init
xor ecx, ecx ; 清空计数器
mov ebx, 2 ; 初始化ebx寄存器为2,表示当前处理的数
cal:
; 判断当前处理的数是否已被标记为1
cmp byte [numbers + ebx], 1
jnz next ; 如果已被标记为1,则跳到next,处理下一个数
inc edi ; 如果没有被标记为1,则表示为一个素数,累加到素数的个数中
; 将所有ebx的倍数位置标记为1
mov esi, ebx
add esi, ebx
mark:
cmp esi, 100000
jge next
mov [numbers + esi], al
add esi, ebx
jmp mark
next:
inc ebx
cmp ebx, 100000
jl cal
; 输出素数的个数
push edi
push output_format
call printf
add esp, 8
ret