format PE64 console
include 'INCLUDE\win64axp.inc'
.code
main:
frame
invoke GetTickCount ;Запросим текущее время в мс
mov [time0],RAX
invoke GetStdHandle, STD_OUTPUT_HANDLE ;Получить handle консоли вывода
mov [hOut],RAX
invoke GetStdHandle, STD_ERROR_HANDLE ;Получить handle консоли ошибок
mov [hErr],RAX
mov R15,0 ;i
mov R14,0 ;kpod
mov R13,0 ;i%385
vzeroupper
vmovdqu ymm0,[.c0] ;Начальные значения остатков
.cycle:
vpcmpeqb ymm7,ymm0,[.noteq2] ;если i%p==no тогда FF, иначе 00
vpmovmskb EBX,ymm7 ;В EAX биты из старшего бита каждого байта из ymm7
mov EAX,EBX
shr EAX,10 ;Сдвинем среднее поле в младшие биты
or EAX,EBX ;Объединяем по or младшую и среднюю часть битовой маски (запрет по 13 и по 17)
shr EBX,20 ;Сдвинем старшее поле в младшие биты
or EAX,EBX ;Объединяем третье поле с первыми двумя
not EAX ;Инвертируем, теперь 1 отвечает подходящим значениям
and EAX,0x3FF ;Выделяем только младшие 10 битов popcnt EAX,EAX ;Подсчитываем количество единичных битов, т.е. подходящих i
add R14,RAX ;Добавляем к счётчику
vpaddb ymm0,ymm0,[.c2] ;i++
vpsubb ymm7,ymm0,[.mods2] ;i-p
vpminub ymm0,ymm0,ymm7 ;(i++)%p
.next: add R15,10
;inc R15
mov RAX,38500000000
cmp R15,RAX
jc .cycle
invoke GetTickCount ;Запросим текущее время в мс
add RAX,1 ;Нулевых интервалов времени работы не допускаем, лучше пусть будет погрешность
sub RAX,[time0] ;Вычтем время старта, получим время работы в мс
xor RDX,RDX ;Старшее слово обнулим
mov RCX,1000 ;Будем делить EDX,EAX на 1000 (количество мс в секунде)
div RCX ;Поделим время на два числа, в секундах и мс
mov R9,RAX
mov R10,RDX
cinvoke wsprintf, buf, .fmt1, R14, R9, R10
invoke WriteFile, dword [hErr], buf, RAX, temp, 0
invoke ExitProcess,0
endf
.fmt1: db '%I64u, time: %u.%03us',13,10,0
align 32
.c0: db 0,1,2,3,4,0,1,2,3,4, 0,1,2,3,4,5,6,0,1,2, 0,1,2,3,4,5,6,7,8,9, 0,0 ;[0..9]%5, [0..9]%7, [0..9]%11, неиспользуемые обнулим и менять не будем
.c2: db 10 dup( 0), 10 dup( 3), 10 dup(10), 0,0 ;10%5=0, 10%7=3, 10%11=10, неиспользуемые увеличивать не будем
.mods2: db 10 dup( 5), 10 dup( 7), 10 dup(11), 0,0 ;и вычитать простое тоже не будем
.noteq2: db 10 dup( 3), 10 dup( 0), 10 dup( 9), 255,255 ;неиспользуемые как были 0, так и останутся, и 0<>255 так что неиспользуемые разрешены всегда
align 32
.data
align 32
time0: rq 1
hOut: rq 1
hErr: rq 1
temp: rq 1
buf: rb 1000
.end main