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
Стек очень быстро заканчивается, потому что параметр передаётся неправильно. Неправильно он передаётся, потому что вводимая строка вообще никак не обрабатывается. 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
не стал глубоко капать, но не верно обрабатываете строку которую ввели с экрана
> Ассемблер.
> ответы мэил ру.
Может тебе лучше в cyberforum.ru зайти?)
> ответы мэил ру.
Может тебе лучше в cyberforum.ru зайти?)
Похожие вопросы
- нужно написать программку на ассемблере, к-рая считает факториал числа n
- как посчитать 365! (С++) Нужен алгоритм вычисления факториала больших чисел.
- Помогите написать на ассемблере програму для вычисления виражения y=(c-(d/2)+33 )/(2*a*a-1). c=5,d=6,a=3.
- Как работает рекурсивная процедура?
- Как на ассемблере написать процедуру для того, чтобы: эл. каждой строки матрицы циклически сдвинуть на 1 эл. влево?!
- Вычисление суммы с факториалом в С++?
- Ассемблер. Написать маленькую программу вычисления арифметического выражения. Подробности внутри.
- С++.Почему программа зацикливается после ввода Х
- Ассемблер!!!! вычисление арифметической функции
- помогите написать программы в ассемблере