2014-02-02 2 views
-1

Я пытаюсь вычислить n! в сборке x86 без использования умножения (я знаю, что он немой, но он проверяет мою способность хранить и манипулировать данными в регистрах). Мне говорят, что вы можете сделать это не слишком много строк сборки.Расчет n! в сборке x86 без использования умножения?

Я знаю, что n! = n * (n-1)! поэтому, если мне нужно вычислить 5! я могу добавить 4! 5 раз (5! = 4! + 4! + 4! + 4! + 4!). Оттуда мне просто нужно вычислить 4! так же вплоть до 2! = 1! + 1! и 1! = 1.

Моя первая мысль использовать цикл как таковой

mov eax, 0 ; clear eax 
mov ecx, n ; because ecx is the loop counter 
next: 
    add eax, (n-1)! ; illegal 
loop next 

Я предполагающей сборки не позволит вам сделать рекурсивный вызов в цикле, как

next: 
    dec edx ; decrement 
    add eax, call nfact; 
loop next 

Where EDX магазины номер для принятия факториала.

Я просто смущен тем, как правильно встраивать петли таким образом, чтобы не разрушать какие-либо данные, которые мне нужны, и все равно получить результат.

EDIT:

Вот как я вычислить умножение с повторным добавлением:

;calulate A*B 

mov eax, a ; 
mov ecx, b ; 
mov ebx, 0 ; this will store a*b 
next: 
add ebx, eax; 
loop next ; ecx is the loop counter that the loop instruction decrements 

;;now ebx has the value a*b; 
+0

Вы можете запомнить данные несколькими различными способами: (1) в регистре, (2) в местах статической памяти (используя 'db',' dw', 'dd' и т. д., директивы сборки или (3) в стеке (используя' push' и 'pop'). – lurker

+0

мой друг также сказал мне, что он сделал это без необходимых данных переменные, поэтому он использовал только регистры, которые действительно заставляют меня думать, как он это сделал. – user3123955

+1

Худший! Искусственный! Ограничение! Ever! :-) – paxdiablo

ответ

0

Шаг 1: Сделайте cmp edx,MAX и ja .tooLarge; где MAX - наибольшее значение n, где n! помещается в 32-бит

Шаг 2: Сделайте mov eax,[lookupTable + edx * 4]

Это 3 инструкции. Таблица поиска не будет очень большой, и ее можно легко предварительно вычислить и сохранить как данные (например, lookupTables dd 0,1,2,...)

+0

идея состоит в том, что нам не нужна таблица поиска, переменные данных не нужны. – user3123955

Смежные вопросы