; Program liczy liczby pierwsze w przedzialach 2-10, 2-100, ..., 2-100.000 ; ; Autor: Bogdan D. ; kontakt: bogdandr (at) op (dot) pl ; ; nasm -O999 -o ile_pier.com -f bin ile_pier.asm ; ; Copyright (C) 2005-2007 Bogdan 'bogdro' Drozdowski, bogdandr @ op . pl ; ; Ten program jest wolnym oprogramowaniem; mozesz go rozpowszechniac ; i/lub modyfikowac zgodnie z licencja GNU Lesser General Public License ; (GNU LGPL) w wersji wydanej przez Fundacje Wolnego Oprogramowania; ; wedlug wersji 3 Licencji lub (jesli wolisz) jednej z pozniejszych wersji. ; ; Ten program jest udostepniany z nadzieja, ze bedzie uzyteczny, lecz ; BEZ JAKIEJKOLWIEK GWARANCJI; nawet domyslnej gwarancji PRZYDATNOSCI ; HANDLOWEJ albo PRZYDATNOSCI DO OKRESLONYCH ZASTOSOWAN. W celu uzyskania ; blizszych informacji - Licencja GNU Lesser General Public License. ; ; Z pewnoscia wraz z niniejszym programem otrzymales tez egzemplarz ; Licencji GNU Lesser General Public License; jesli nie - napisz do ; Fundacji Wolnego Oprogramowania: ; Free Software Foundation ; 51 Franklin Street, Fifth Floor ; Boston, MA 02110-1301 ; USA org 100h start: xor ebx, ebx xor edi, edi ; EDI = biezacy licznik liczb inc ebx xor ecx, ecx ; stary licznik liczb (z poprzedniego ; przedzialu) mov esi, 10 ; ESI = biezacy koniec przedzialu inc edi ; uwzgledniamy 2 inc ebx ; EBX=2, pierwsza liczba bedzie = 3 petla: cmp ebx, esi ; czy koniec przedzialu? jae pisz ; jesli tak, to wypisz wyniki obliczen mov ebp, 2 ; pierwszy dzielnik = 2 inc ebx ; zwiekszamy liczbe spr: mov eax, ebx ; EAX = liczba xor edx, edx div ebp ; dzielimy przez potencjalny dzielnik or edx, edx ; jezeli dzieli sie bez reszty, to nie ; jest pierwsza jz petla ; i trzeba wybrac nowego kandydata inc ebp ; zwiekszamy dzielnik cmp ebp,ebx ; dzielniki <= liczba jb spr juz: ; przerobilismy wszystkie dzielniki, ; zawsze wychodzila ; reszta, wiec liczba badana ; jest pierwsza inc edi ;zwiekszamy licznik liczb znalezionych jmp short petla ; od nowa ;=========================================== pisz: ; wyswietlamy wyniki poszukiwan mov edx, przedzial mov ah, 9 int 21h mov eax, esi call _pisz_ld ; wyswietla liczbe z EAX (granice ; przedzialu) mov ax, (0eh << 8) | ':' int 10h ; wyswietlamy dwukropek add ecx, edi ; dodajemy poprzednia ilosc mov eax, ecx call _pisz_ld ; wyswietla liczbe z EAX (ilosc ; znalezionych liczb) ;=========================================== mov ah, 1 int 16h ; sprawdzamy, czy nacisnieto klawisz jz dalej ; jesli nie, to sprawdzamy kolejny ; przedzial xor ah, ah int 16h koniec: mov ax, 4c00h int 21h ; wychodzimy z programu dalej: cmp esi, 100000 ; 10^5 je koniec ; jesli koniec ustalonego limitu, ; to wychodzimy mov eax, esi shl eax, 3 shl esi, 1 add esi, eax ; ESI = ESI*10 xor edi, edi ; zrujemy biezacy licznik liczb jmp short petla ; i liczymy liczby pierwsze w nowym ; przedziale przedzial db 10,13,'Przedzial 2-$' ;************************************** _pisz_bufor times 6 db 0 ;************************************** _pisz_ld: ;we: EAX=liczba bez znaku do wypisania push ecx push edx push eax push esi xor si,si mov ecx,10 ; bedziemy dzielic przez 10 _pisz_ld_petla: xor edx,edx div ecx ; dziel przez 10 mov [_pisz_bufor+si],dl ; zachowaj reszte inc si or eax,eax jnz _pisz_ld_petla ; jesli wynik rozny od zera, to go ; dalej dziel mov ah,0eh _pisz_ld_wypis: mov al,[_pisz_bufor+si-1] ; wypisuj reszty wspak, aby otrzymac ; prawidlowy wynik or al,'0' int 10h dec si jnz _pisz_ld_wypis pop esi pop eax pop edx pop ecx ret