Первые 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
. - Выводится пробел.
- Значение текущего элемента массива
- Выводится перевод строки.
- Устанавливается
- Программа завершается.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д