Итеративное дополнение сборки MASM x86 для вычисления факториалов

У меня тут проблема.
Мне нужно создать один цикл, который берет заданное число (сохраненное в ebx) и вычисляет его факториал, но я хоть убей, не могу понять, как это сделать. Мой ограничивающий фактор заключается в том, что вы не можете использовать какие-либо команды умножения.
Вот основной формат проблемы:

;preceding code
mov eax, 0 ;n! will be stored in eax
ecx = ebx ;ebx = n

factorial: ;computes n! 
  ;some algorithm I have not figured out
  ;
  ;
loop factorial

;eax = n!

Любые идеи о том, что этот алгоритм может быть?

ОБНОВЛЕНИЕ: я нашел алгоритм, мне пришлось написать его на C, потому что я гораздо лучше разбираюсь в этом, чем в сборке x86.

int x = z; //z is the number we want z! from
int y = 0;
int n = x;
int i, j;

for(i = x - 1; i > 0; i--)
{
  for(j = n; j > 0; j--)
    y += i;
  n = y;
  y = 0;
}
printf("%d\n", n);

В данный момент пытаемся перевести на Assembly.

ЗДЕСЬ окончательный перевод/ответ для всех будущих кодеров. Вопрос решен.

;FACTORIAL WITHOUT MULTIPLICATION
mov ecx, ebx   
mov edx, 0
mov eax, ebx
dec ecx
jz next
factorial:
  mov edi, ecx
  mov ecx, eax
  factorial2:
    add edx, edi       
  loop factorial2
  mov ecx, edi
  mov eax, edx
  mov edx, 0
loop factorial  

person Sam W.    schedule 30.01.2014    source источник


Ответы (1)


Ну, так как наибольший факториал, который может быть сохранен в 32-битном целом числе, равен 12! использование цикла не требуется. Гораздо проще и быстрее просто хранить факториалы в таблице и искать их.

Код без проверки диапазона может выглядеть примерно так:

  ; assumes n is stored in EBX

  lea edi, [FactorialTable]
  mov eax, [edi + ebx*4]
  ret                          ; return from subroutine

FactorialTable:
  dd 1  ; factorial of 0 is 1
  dd 1
  dd 2
  dd 6
  dd 24
  dd 120
  dd 720
  dd 5040
  dd 40320
  dd 362880
  dd 3628800
  dd 39916800
  dd 479001600
person Nils Pipenbrinck    schedule 30.01.2014
comment
Спасибо за комментарий! Но на самом деле мне нужно вычислить его для задания, а не для реальных приложений (конечно, таблица была бы лучше!). Кроме того, я работаю только с целыми числами 1-10, поэтому 32-битный подходит для 10!. - person Sam W.; 31.01.2014