Другие языки программирования и технологии

Ассемблер рекурсивная процедура. вычисление факториала, в чем проблемма программы? в отладчике она зацикливается.

s_s segment stack
dw 20 dup (?);определяем 20 слов в сегменте стека
s_s ends
d_s segment
fact1 dw 10,13,'$';определяем двухбайтовые ячейки для факториала
res1 dw ?;определяем ячейки для результата
d_s ends
c_s segment
assume ss:s_s, ds:d_s, cs:c_s
begin:
mov ax,d_s
mov ds,ax
xor ax,ax

mov dx, offset fact1
mov ah,0Ah
int 21h

mov bx,1;заносим в BX единицу
mov ax, fact1;заносим в AX значение по адресу fact1
push ax;вталкиваем AX в стек
xor ax,ax;очищаем регистр
call factorial;вызываем ближнюю процедуру factorial
mov res1,ax;заносим содержание AX в ячейку res1

jmp exit;переходим к завершению программы

factorial proc near;ближняя процедура factorial
push bp;вталкиваем в стек значение регистра BP
mov bp,sp;заносим значение вершины стека в BP

mov cx, [bp+4];заносим в CX значение в стеке по адресу BX+4
mov ax, cx;копируем CX в AX
mul bx;умножаем AX на BX
mov bx, ax;заносим AX в BX
dec cx;декреминируем CX
jcxz end_proc;анализируем флаг ZF: если в CX ноль, то переход
push cx;иначе вталкиваем CX в стек
call factorial;вызываем ближнюю процедуру factorial
end_proc: mov sp,bp;метка end_proc: заносим значение BP в вершину стека

pop bp;выталкиваем BP из стека
ret;выход из процедуры
factorial endp

exit: mov ah,4ch;выход из программы
int 21h
c_s ends
end begin
Здесь целый букет причин зацикливания.
Стек очень быстро заканчивается, потому что параметр передаётся неправильно. Неправильно он передаётся, потому что вводимая строка вообще никак не обрабатывается. cx при входе в рекурсию просто теряется.
Не восстанавливается указатель стека в главном теле программы.
И комментарии у вас просто шикарные: "Это круг, он круглый. Это прямая линия, она прямая".

Исправленная программа. Допускается ввод чисел от 0 до 8. На любые другие символы реагирует выдачей сообщения об ошибке. Для чисел 0 ...8 выводит на экран значение факториала.

s_s segment stack
  dw 256 dup (?)
s_s ends

d_s segment
  fact1 db 2, 3 dup (?)
  res1 dw ?
  ErrMsg db 13, 10, "Ошибка! ", 13, 10, 36
d_s ends

c_s segment
    assume ss:s_s, ds:d_s, cs:c_s
begin:
    mov ax, d_s
    mov ds, ax
   
Repeat:
    mov dx, offset fact1
    mov ah, 0Ah
    int 21h
    mov al, fact1 + 1
    test al, al
    je Error
    mov al, fact1 + 2
    sub al, '0'
    cmp al, 8
    jbe NoError
Error:
    mov dx, offset ErrMsg
    mov ah, 9
    int 21h
    jmp Repeat

NoError:
    cbw
    push ax
    call factorial
    add sp, 2
    mov res1, ax
    mov al, 10
    int 29h
   
    mov ax, res1
    xor cx, cx
    mov bx, 10
Prepare:
    xor dx, dx
    div bx
    or dl, '0'
    push dx
    inc cx
    test ax, ax
    jne Prepare
Print:
    pop ax
    int 29h
    loop Print

    mov ah, 7
    int 21h
    mov ah, 4ch
    int 21h

factorial proc near
    push bp
    mov bp, sp
    mov cx, [bp + 4]
    jcxz Zero
    push cx
    dec cx
    push cx
    call factorial
    pop cx
    pop cx
    mul cx
    jmp end_proc
Zero:
    mov ax, 1
end_proc:
    pop bp
    ret
factorial endp

c_s ends
    end begin
Станислав Юдин
Станислав Юдин
51 590
Лучший ответ
не стал глубоко капать, но не верно обрабатываете строку которую ввели с экрана
Rustam Mextiyev
Rustam Mextiyev
1 786
> Ассемблер.
> ответы мэил ру.
Может тебе лучше в cyberforum.ru зайти?)
AI
Asif Ibadov
266