Типа микроупражнения. Надеюсь такого не было. Необходимо проверить делится ли число n на 7 не используя операций деления и умножения. Вход: eax = n, 0 < n < 4294967296. Выход: zf = 1, если (n mod 7) = 0. Иначе zf = 0. P.S. Деление в столбик будет не лучшим решением
Код (Text): test7: mov edx,eax and edx,7 shr eax,3 add eax,edx cmp eax,7 ja test7 jz .exit xor eax,7 .exit: ret
cresta Если бы не было, то я бы и не запостил. Этож не практическая задача. Сама собой в голову пришло. Может кому-то еще интересно найти решение.
Black_mirror метод работает, если бинарное представление делителя состоит из одних единиц. (1,3,7,15,31...). А если взять другие числа из известной "тройки" 7-11-13: например 11?
_G3 Ну раз n>0, тогда так Код (Text): test7: mov edx,eax and eax,7 shr edx,3 add eax,edx sub eax,7 ja test7 ret
cresta Если я ничего не напутал, тогда Код (Text): test11: mov edx,eax shr eax,5 and edx,31 sub eax,edx jg test11 sub eax,11 .l: add eax,11 js .l ret test13: mov edx,eax shr eax,6 and edx,63 sub eax,edx jg test13 sub eax,13 .l: add eax,13 js .l ret test17: mov edx,eax shr eax,4 and edx,15 sub eax,edx jg test17 sub eax,17 .l: add eax,17 js .l ret
Black_mirror Супер! Я до такого не допер. Вот мое решение: Код (Text): xor ebx,ebx L10: add eax,ebx mov ebx,eax and ebx,7 shr eax,3 jnz L10 cmp ebx,7
Black_mirror Здорово. Я пытался как-то применить этот метод к 11 и 13, но нифига не получалось. Оказывается решение есть
n>0? Тогда самый короткий (но не самый быстрый) вариант такой: Код (Text): l1: sub eax, 7 ja l1 ...но это брутфорс.
Можно воспользоваться арифметикой остатков. Например, частный случай (трехзначное число): (a<sub>2</sub>*10<sup>2</sup>+a<sub>1</sub>*10+a<sub>0</sub>)mod 7 сравнимо с (a<sub>2</sub>+a<sub>1</sub>*3+a<sub>0</sub>)mod 7 и всё это должно быть сравнимо с 0 по модулю 7. Итак, a<sub>2</sub>+a<sub>1</sub>*3+a<sub>0</sub> должно быть кратно 7-ми. Аналогично для чисел более высоких порядков. Ну а разделить вышеприведенную сумму на 7 можно и брутфорсом
Dimson Но проц считает не в 10-й системе счисления. Сначала число туда перевести надо. Лучше распиши свой алгоритм для 8-й системы и получишь такое же решение как приводились выше.
Продолжаем проверять делимость: Код (Text): test19: mov edx,eax and edx,15 shr eax,4 lea eax,[eax*3] sub eax,edx jg test19 sub eax,19 .l: add eax,19 js .l ret test23: mov edx,eax and edx,15 shr eax,4 imul eax,7; лень сдвигами делать sub eax,edx jg test23 sub eax,23 .l: add eax,23 js .l ret Что-то мне цикл с меткой .l совсем не нравится, вернее не нравится что перед ним нужно корректировать регистр, чтобы не пропустить случай, когда регистр уже равен нулю. Есть идеи как от этого избавиться?
Black_mirror Проверить на 19 можно также как ты для 11,13,17 предложил: Код (Text): test19: mov edx,eax shr eax,9 and edx,511 sub eax,edx jg test19 sub eax,19 .l: add eax,19 js .l
Если слегка изменить требования: 1)public mul 2)Выход: cf Код (Text): cmp eax, 05555555Ah jbe @F sub eax, 055555554h cmp eax, 05555555Ah jbe @F sub eax, 055555554h @@: imul eax,024924925h cmp eax,024924925h Работает от одного до пяти раз быстрее, в зависимости от размера источника