Hi all собственно субж. как-то по долгу учебы реальзовывал сложение, вычитание, умножение и деление исключительно при помощи лог.операций но исходник к сожелению утерян. а тут стало интересно=) Заранее благодарен =)
Пардон, xor в списке разрешенных инструкций нет. Тогда: Код (Text): op_add: push ebp mov ebp, esp mov eax, [ebp + 0x8] and eax, [ebp + 0xC] not eax mov edx, [ebp + 0x8] or edx, [ebp + 0xC] and eax, edx mov edx, [ebp + 0x8] and edx, [ebp + 0xC] shl edx, 0x1 or eax, edx mov esp, ebp pop ebp ret
Как реализовать inc используя только and not shl shr впрочем, спор ни о чем: a|b= !(!a&!b) a^b=a!b | !ab хуже то, что все вышеперечисленные решения работают только для одноразрядных чисел
Mika0x65 Думаю, это невозможно, хотя доказательства не предложу. Но можно попробовать рассуждать следующим образом: Есть большое количество различных (не криптографических) checksum- и hash-функций. Некоторые, как adler32 или sdbm, работают на сложении и умножении и являются таким образом линейными в Z. Соответственно их легко обратить (Хеш функция). Некоторые, вроде примера Кнута, используют только битовые операции и являются таким образом линейными в соответствующем кольце полиномов. Опять же без проблем обращаются. Сложности начинаются тогда, когда вперемешку используются арифметические и битовые операции, пример - улучшенная версия djb. Если бы можно было свести сложение к битовым операциям, то в результате ее также стало бы возможно обратить. А поскольку это было бы слишком хорошо, чтобы быть правдой, то и выразить сложение через битовые операции не удастся Если где напутал, поправляйте.
Сложение можно сделать таким циклом: do{ C=A and B; A=A xor B=(not ((not A) and (not B))) and (not C); B=C shl 1; }while(B); В худшем случае выполняется столько раз, какова разрядность слова, поэтому его можно и развернуть.
называется суматор с параллельным переносом чем больше номер разряда, тем больше получается формула, но работают значительно быстрее (про больших разрядностях в несколько раз) последовательных сумматоров (или сумматоров с последовательным переносом), но большие апаратные затраты... Выгодной с точки зрения аппаратных затрат являются последовательно-параллельные сумматоры... формулы для последовательного инкрементора Q=A xor C0; W=A and C0; A текущий разряд С0 входной перенос (в 0 разряде = 1 если нужен инкремент) W выходной пперенос Q результирующий бит в проге будет выглядеть примерно так (не проверял) char A[32],Q[32],c0; // c0=1; while (i<32 && c0) { Q = A ^^ c0; c0 = A && c0; }