📄 primes.asm
字号:
; thanks to Scali .. he helped optimizing this
.386
.model flat, stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
inv equ invoke
.data
hFile dd 0
BW dd 0
ofstruct OFSTRUCT <>
szPrime db "%lu, ", 0
szCaption db "Done!", 0
szDone db "Done! The number of primes found is: %lu", 13, 10, \
"Wrote primes to "
szFile db "PRIMES.TXT", 0
.data?
buffer dw 0ffffh dup (?)
szTemp db 80 dup (?)
.code
start:
mov ecx, 0ffffh / 2 ; counter
mov edi, offset buffer ; here: offset for where to put the numbers
mov eax, 00030002h ; write 2 numbers at one time
mov esi, edi ; where to read the numbers from (for the next step)
createbuffer_loop:
mov [edi], eax ; put 2 numbers into the buffer
add eax, 00020002h ; increase the number that gets put in the buffer
add edi, 4 ; adjust the buffer pointer
dec ecx ; decrease the counter
jnz createbuffer_loop ; counter <> zero? then do the whole thing again
mov edi, esi ; now restore edi for later
mov ecx, 0ffffh / 2 ; counter
xor ebx, ebx ; ebx will hold the number of primes
xor edx, edx ; clear high part of edx, because it will be used as pointer
findprime_loop:
mov ax, [esi] ; get the first word from the buffer
add esi, 2 ; adjust the buffer pointer
test ax, ax ; ax == zero?
jz no_prime ; then this is already a killed number
inc ebx ; we are here so this is a prime. increase the prime counter
mov dx, ax ; put the prime into dx
eliminatenonprime_loop:
add dx, ax ; now add the prime to the prime (prime*2, later prime*3 ..)
jc no_prime ; if dx now grew over 0ffffh, there's nothing left to kill
mov word ptr [edx*2+buffer-4], 0 ; kill non-primes by marking them with zero
jmp eliminatenonprime_loop ; jump back, till dx > 0ffffh
no_prime:
dec ecx ; decrease the counter
jnz findprime_loop ; counter <> zero? then do it again
push ebx ; because some APIs change ebx, we have to save it on the stack
inv OpenFile, offset szFile, offset ofstruct, OF_CREATE ; create new file
mov hFile, eax ; save its handle
mov cx, 0ffffh ; put counter to 0ffffh
xor eax, eax ; clear high parts of eax.
write:
push cx ; save cx on the stack, because one of these APIs will change it
mov ax, [edi] ; normally I'd use esi here, but I restored edi in the beginning
add edi, 2 ; adjust ...
test ax, ax ; ax == zero?
jz skip_write ; yes? so this is a killed number. do nothing
inv wsprintf, offset szTemp, offset szPrime, eax ; else convert number to ASCII
inv WriteFile, hFile, offset szTemp, eax, offset BW, NULL ; and write it to the file
skip_write:
pop cx ; restore the counter
dec cx ; and decrease it
jnz write ; zero? if not, then go back again
inv CloseHandle, hFile ; close the file
pop ebx ; pop the prime counter from the stack
inv wsprintf, offset szTemp, offset szDone, ebx
inv MessageBox, 0, offset szTemp, offset szCaption, MB_OK
inv ExitProcess, 0
end start
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -