Первые n строк треугольника Паскаля (TASM) - Assembler
Формулировка задачи:
Доброго вечера!
Есть задача:
С клавиатуры вводится N (DW). Получить первые N строк треугольника Паскаля. Задача на тему "Матрицы".
Вот что я смог состряпать самостоятельно:
По поводу inint, outstr, newline - это наши "шаблонные" процедурки, которые выдали в университете.
inint - считывает с клавиатуры число размером в слово
outstr - выводит строку, расположенную в dx
newline - переход на следующую строку
Программа, по идее, должна выводить треугольник паскаля, но выводит матрицу со всеми нулевыми элементами, кроме диагональных. На диагоналях остаются единицы.
Помогите, пожалуйста, доделать ее.
Всем спасибо!
Листинг программы
- lea dx, msg1
- outstr
- inint N
- mov ax, N
- mul dva
- mov P1, ax ;P1 = 2*N
- add ax, 2
- mov p2, ax ;p2 = 2*n + 2
- mov cx, N
- xor bx, bx
- BEG:
- mov A[bx], 1
- add bx, p1
- loop BEG ;здесь заполняются единицами элементы первого столбца
- mov cx, N
- xor bx, bx
- BEG10:
- mov A[bx], 1
- add bx, p2 ;здесь заполняются единицами диагональными элементами
- loop BEG10
- ;
- ;for i:=2 to N do
- ; for j:=1 to i-1 do
- ; a[i,j]:=a[i-1,j-1]+a[i-1,j];
- ; Это паскалевский эквивалент вложенных циклов
- xor bx, bx
- mov cx, N
- dec cx
- mov I, 2
- FORI:
- push cx
- mov J, 1
- mov cx, I
- dec cx
- FORJ:
- mov ax, I
- sub ax, 2
- mul n
- add ax, j
- sub ax, 2
- mul dva
- mov bx, ax
- mov dx, A[bx] ;Здесь подсчитывается a[i-1,j-1]
- mov ax, I
- sub ax, 2
- mul N
- add ax, j
- dec ax
- mul dva
- mov bx, ax
- add dx, A[bx] ;Здесь подсчитывается a[i-1,j-1]+a[i-1,j]
- mov ax, I
- dec ax
- mul n
- add ax, j
- dec ax
- mul dva
- mov bx, ax
- mov A[bx], dx ;a[i,j] := a[i-1,j-1]+a[i-1,j]
- inc J
- loop FORJ
- pop cx
- inc I
- loop FORI
- ;=================================================================================
- xor bx, bx
- mov cx, N
- BEG1:
- push cx
- mov cx, N
- ;Это просто вывод в виде матрицы
- BEG2:
- outint A[bx],4
- add bx, 2
- loop BEG2
- newline
- pop cx
- Loop BEG1
Видимо встал не стой ноги и начал писать какую-то ахинею.
Переписал без всяких i и j.
Вот работающий код:
Листинг программы
- lea dx, msg1
- outstr
- inint N
- mov ax, N
- mul dva
- mov P1, ax ;P1 = 2*N
- add ax, 2
- mov p2, ax ;p2 = 2*n + 2
- mov cx, N
- xor bx, bx
- BEG:
- mov A[bx], 1
- add bx, p1 ;заполняем элементы первого столбца единицами
- loop BEG
- mov cx, N
- xor bx, bx
- BEG10:
- mov A[bx], 1
- add bx, p2 ;заполняем диагональные элементы единицами
- loop BEG10
- mov cx, N
- sub cx, 2
- xor si, si
- mov bx, p2
- add bx, p1 ;bx = 4*N+2 - переход на первый элемент в матрице, который требует обработки
- mov di, bx ;Вспомогательное приращение
- mov gr, 1 ;Счетчик числа итераций для внутреннего цикла
- CKL1: ;for i:= 2 to N
- push cx
- mov cx, gr ;for j:= 1 to gr
- CKL2:
- mov si, bx
- sub si, p2
- mov dx, a[si] ;dx = a[i-1,j-1]
- mov si, bx
- sub si, p1
- add dx, a[si] ;dx = a[i-1,j-1]+a[i-1,j]
- mov a[bx], dx ;a[i,j] = dx
- add bx, 2
- loop CKL2
- pop cx
- add di, p1 ;di = di + 2*n
- mov bx, di ;таким образом осуществляется переход на следующий элемент, требующий обработки
- inc gr
- loop CKL1
- ;=================================================================================
- xor bx, bx
- mov cx, N
- BEG1:
- push cx
- mov cx, N
- BEG2:
- outint A[bx],4
- add bx, 2 ;Вывод в виде матрицы
- loop BEG2
- newline
- pop cx
- Loop BEG1
Решение задачи: «Первые n строк треугольника Паскаля (TASM)»
textual
Листинг программы
- .model small
- .stack 100h
- .data
- Nmax equ 18 ;максимальное значение N, при котором все значения
- ;треугольника Паскаля не превышают ёмкости 16-разрядной перемменной
- N dw 17 ;количество выводимых строк
- A dw Nmax dup (?) ;текущая (выводимая) строка треугольника Паскаля
- elSize equ 2 ;размер элемента массива
- CrLf db 0Dh, 0Ah, '$' ;символы перевода строки
- .code
- main proc
- mov ax, @data ;begin
- mov ds, ax
- cmp N, Nmax ; if N > Nmax then
- jbe @@ShowTriangle
- mov N, word ptr Nmax ; N := Nmax;
- @@ShowTriangle:
- mov A[0], word ptr 1 ; a[1] := 1;
- mov cx, N ; for i := 1 to n do
- @@For_I:
- mov bx, 0 ; tmp2 := 0;
- lea si, [A] ; for j := 1 to i do
- push cx
- mov ax, N
- sub ax, cx
- inc ax
- mov cx, ax
- @@For_J: ; begin
- mov ax, [si] ; tmp1 := a[j];
- add bx, ax ; a[j] := tmp2 + a[j];
- mov [si], bx
- xchg bx, ax ; tmp2 := tmp1;
- call Show_AX ; Write(a[j]: 10);
- call WriteSpace
- add si, elSize ; end;
- loop @@For_J
- pop cx
- call NewLine ; writeln;
- loop @@For_I ; end;
- ;завершение программы
- mov ax, 4C00h ;end.
- int 21h
- main endp
- ; выводит знаковое 16-разрядное число из регистра AX на экран
- ; входные данные:
- ; ax - число для отображения
- Show_AX proc
- push ax
- push bx
- push cx
- push dx
- push di
- mov cx, 10 ; основание системы счисления
- xor di, di ; di - кол. цифр в числе
- @@Conv:
- xor dx, dx
- div cx ; dl = num mod 10
- add dl, '0' ; перевод в символьный формат
- inc di
- push dx ; складываем в стек
- or ax, ax
- jnz @@Conv
- ; выводим из стека на экран
- @@Show:
- pop dx ; dl = очередной выводимый символ
- mov ah, 2 ; ah - функция вывода символа на экран
- int 21h
- dec di ; повторяем пока di<>0
- jnz @@Show
- pop di
- pop dx
- pop cx
- pop bx
- pop ax
- ret
- Show_AX endp
- ; Вывод на экран одного пробела
- ; входные данные:
- ; - нет
- WriteSpace proc
- push ax
- mov al, ' '
- int 29h
- pop ax
- ret
- WriteSpace endp
- ; Вывод на экран одного перевода строки
- ; входные данные:
- ; - нет
- NewLine proc
- push ax
- push bx
- push cx
- mov ah, 09h
- lea dx, [CrLf]
- int 21h
- pop cx
- pop bx
- pop ax
- ret
- NewLine endp
- end main
Объяснение кода листинга программы
- Объявляются переменные:
Nmax
с 18N
с 17A
с пустыми 18-разрядными значениямиelSize
с 2CrLf
с символами перевода строки
- Сравнивается значение переменной
N
сNmax
. ЕслиN
большеNmax
, то значениеN
заменяется наNmax
. - В первый элемент массива
A
записывается значение 1. - Устанавливается значение
cx
равнымN
. - Начинается цикл от 0 до
N
:- Устанавливается
bx
в 0. - Перебираются все элементы массива
A
от 1 доi
:- Значение текущего элемента массива
A
(a[j]
) записывается вax
. bx
прибавляется кax
и результат записывается обратно вa[j]
.- Обмен значениями между
bx
иax
. - Выводится значение
ax
. - Выводится пробел.
- Значение текущего элемента массива
- Выводится перевод строки.
- Устанавливается
- Программа завершается.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д