Первые n строк треугольника Паскаля (TASM) - Assembler

Узнай цену своей работы

Формулировка задачи:

Доброго вечера! Есть задача: С клавиатуры вводится N (DW). Получить первые N строк треугольника Паскаля. Задача на тему "Матрицы". Вот что я смог состряпать самостоятельно:
Листинг программы
  1. lea dx, msg1
  2. outstr
  3. inint N
  4.  
  5. mov ax, N
  6. mul dva
  7. mov P1, ax ;P1 = 2*N
  8. add ax, 2
  9. mov p2, ax ;p2 = 2*n + 2
  10. mov cx, N
  11. xor bx, bx
  12. BEG:
  13. mov A[bx], 1
  14. add bx, p1
  15. loop BEG ;здесь заполняются единицами элементы первого столбца
  16. mov cx, N
  17. xor bx, bx
  18. BEG10:
  19. mov A[bx], 1
  20. add bx, p2 ;здесь заполняются единицами диагональными элементами
  21. loop BEG10
  22. ;
  23. ;for i:=2 to N do
  24. ; for j:=1 to i-1 do
  25. ; a[i,j]:=a[i-1,j-1]+a[i-1,j];
  26.  
  27. ; Это паскалевский эквивалент вложенных циклов
  28. xor bx, bx
  29. mov cx, N
  30. dec cx
  31. mov I, 2
  32. FORI:
  33. push cx
  34. mov J, 1
  35. mov cx, I
  36. dec cx
  37. FORJ:
  38. mov ax, I
  39. sub ax, 2
  40. mul n
  41. add ax, j
  42. sub ax, 2
  43. mul dva
  44. mov bx, ax
  45. mov dx, A[bx] ;Здесь подсчитывается a[i-1,j-1]
  46. mov ax, I
  47. sub ax, 2
  48. mul N
  49. add ax, j
  50. dec ax
  51. mul dva
  52. mov bx, ax
  53. add dx, A[bx] ;Здесь подсчитывается a[i-1,j-1]+a[i-1,j]
  54. mov ax, I
  55. dec ax
  56. mul n
  57. add ax, j
  58. dec ax
  59. mul dva
  60. mov bx, ax
  61. mov A[bx], dx ;a[i,j] := a[i-1,j-1]+a[i-1,j]
  62. inc J
  63. loop FORJ
  64. pop cx
  65. inc I
  66. loop FORI
  67. ;=================================================================================
  68. xor bx, bx
  69. mov cx, N
  70. BEG1:
  71. push cx
  72. mov cx, N
  73. ;Это просто вывод в виде матрицы
  74. BEG2:
  75. outint A[bx],4
  76. add bx, 2
  77. loop BEG2
  78. newline
  79. pop cx
  80. Loop BEG1
По поводу inint, outstr, newline - это наши "шаблонные" процедурки, которые выдали в университете. inint - считывает с клавиатуры число размером в слово outstr - выводит строку, расположенную в dx newline - переход на следующую строку Программа, по идее, должна выводить треугольник паскаля, но выводит матрицу со всеми нулевыми элементами, кроме диагональных. На диагоналях остаются единицы. Помогите, пожалуйста, доделать ее.
Видимо встал не стой ноги и начал писать какую-то ахинею. Переписал без всяких i и j. Вот работающий код:
Листинг программы
  1. lea dx, msg1
  2. outstr
  3. inint N
  4.  
  5. mov ax, N
  6. mul dva
  7. mov P1, ax ;P1 = 2*N
  8. add ax, 2
  9. mov p2, ax ;p2 = 2*n + 2
  10. mov cx, N
  11. xor bx, bx
  12. BEG:
  13. mov A[bx], 1
  14. add bx, p1 ;заполняем элементы первого столбца единицами
  15. loop BEG
  16. mov cx, N
  17. xor bx, bx
  18. BEG10:
  19. mov A[bx], 1
  20. add bx, p2 ;заполняем диагональные элементы единицами
  21. loop BEG10
  22. mov cx, N
  23. sub cx, 2
  24. xor si, si
  25. mov bx, p2
  26. add bx, p1 ;bx = 4*N+2 - переход на первый элемент в матрице, который требует обработки
  27. mov di, bx ;Вспомогательное приращение
  28. mov gr, 1 ;Счетчик числа итераций для внутреннего цикла
  29. CKL1: ;for i:= 2 to N
  30. push cx
  31. mov cx, gr ;for j:= 1 to gr
  32. CKL2:
  33. mov si, bx
  34. sub si, p2
  35. mov dx, a[si] ;dx = a[i-1,j-1]
  36. mov si, bx
  37. sub si, p1
  38. add dx, a[si] ;dx = a[i-1,j-1]+a[i-1,j]
  39. mov a[bx], dx ;a[i,j] = dx
  40. add bx, 2
  41. loop CKL2
  42. pop cx
  43. add di, p1 ;di = di + 2*n
  44. mov bx, di ;таким образом осуществляется переход на следующий элемент, требующий обработки
  45. inc gr
  46. loop CKL1
  47.  
  48. ;=================================================================================
  49. xor bx, bx
  50. mov cx, N
  51. BEG1:
  52. push cx
  53. mov cx, N
  54. BEG2:
  55. outint A[bx],4
  56. add bx, 2 ;Вывод в виде матрицы
  57. loop BEG2
  58. newline
  59. pop cx
  60. Loop BEG1
Всем спасибо!

Решение задачи: «Первые n строк треугольника Паскаля (TASM)»

textual
Листинг программы
  1. .model small
  2.  
  3. .stack 100h
  4.  
  5. .data
  6.         Nmax    equ     18              ;максимальное значение N, при котором все значения
  7.                                         ;треугольника Паскаля не превышают ёмкости 16-разрядной перемменной
  8.         N       dw      17              ;количество выводимых строк
  9.         A       dw      Nmax dup (?)    ;текущая (выводимая) строка треугольника Паскаля
  10.         elSize  equ     2               ;размер элемента массива
  11.         CrLf    db      0Dh, 0Ah, '$'   ;символы перевода строки
  12.  
  13. .code
  14.  
  15. main    proc
  16.         mov     ax,     @data           ;begin
  17.         mov     ds,     ax
  18.  
  19.         cmp     N,      Nmax            ;  if N > Nmax then
  20.         jbe     @@ShowTriangle
  21.         mov     N,      word ptr Nmax   ;    N := Nmax;
  22. @@ShowTriangle:
  23.  
  24.         mov     A[0],   word ptr 1      ;  a[1] := 1;
  25.         mov     cx,     N               ;  for i := 1 to n do
  26. @@For_I:
  27.         mov     bx,     0               ;    tmp2 := 0;
  28.         lea     si,     [A]             ;    for j := 1 to i do
  29.         push    cx
  30.         mov     ax,     N
  31.         sub     ax,     cx
  32.         inc     ax
  33.         mov     cx,     ax
  34.         @@For_J:                        ;    begin
  35.  
  36.                 mov     ax,     [si]    ;      tmp1 := a[j];
  37.                 add     bx,     ax      ;      a[j] := tmp2 + a[j];
  38.                 mov     [si],   bx
  39.                 xchg    bx,     ax      ;      tmp2 := tmp1;
  40.  
  41.                 call    Show_AX         ;      Write(a[j]: 10);
  42.                 call    WriteSpace
  43.  
  44.                 add     si,     elSize  ;    end;
  45.                 loop    @@For_J
  46.         pop     cx
  47.  
  48.         call    NewLine                 ;    writeln;
  49.         loop    @@For_I                 ;  end;
  50.  
  51.         ;завершение программы
  52.         mov     ax,     4C00h           ;end.
  53.         int     21h
  54. main    endp
  55.  
  56. ; выводит знаковое 16-разрядное число из регистра AX на экран
  57. ; входные данные:
  58. ; ax - число для отображения
  59. Show_AX proc
  60.         push    ax
  61.         push    bx
  62.         push    cx
  63.         push    dx
  64.         push    di
  65.  
  66.         mov     cx,     10      ; основание системы счисления
  67.         xor     di,     di      ; di - кол. цифр в числе
  68.  
  69. @@Conv:
  70.         xor     dx,     dx
  71.         div     cx              ; dl = num mod 10
  72.         add     dl,     '0'     ; перевод в символьный формат
  73.         inc     di
  74.         push    dx              ; складываем в стек
  75.         or      ax,     ax
  76.         jnz     @@Conv
  77.         ; выводим из стека на экран
  78. @@Show:
  79.         pop     dx              ; dl = очередной выводимый символ
  80.         mov     ah,     2       ; ah - функция вывода символа на экран
  81.         int     21h
  82.         dec     di              ; повторяем пока di<>0
  83.         jnz     @@Show
  84.  
  85.         pop     di
  86.         pop     dx
  87.         pop     cx
  88.         pop     bx
  89.         pop     ax
  90.         ret
  91. Show_AX endp
  92.  
  93. ; Вывод на экран одного пробела
  94. ; входные данные:
  95. ; - нет
  96. WriteSpace      proc
  97.         push    ax
  98.         mov     al,     ' '
  99.         int     29h
  100.         pop     ax
  101.         ret
  102. WriteSpace      endp
  103.  
  104. ; Вывод на экран одного перевода строки
  105. ; входные данные:
  106. ; - нет
  107. NewLine proc
  108.         push    ax
  109.         push    bx
  110.         push    cx
  111.         mov     ah,     09h
  112.         lea     dx,     [CrLf]
  113.         int     21h
  114.         pop     cx
  115.         pop     bx
  116.         pop     ax
  117.         ret
  118. NewLine endp
  119.  
  120. end     main

Объяснение кода листинга программы

  1. Объявляются переменные:
    • Nmax с 18
    • N с 17
    • A с пустыми 18-разрядными значениями
    • elSize с 2
    • CrLf с символами перевода строки
  2. Сравнивается значение переменной N с Nmax. Если N больше Nmax, то значение N заменяется на Nmax.
  3. В первый элемент массива A записывается значение 1.
  4. Устанавливается значение cx равным N.
  5. Начинается цикл от 0 до N:
    • Устанавливается bx в 0.
    • Перебираются все элементы массива A от 1 до i:
      • Значение текущего элемента массива A (a[j]) записывается в ax.
      • bx прибавляется к ax и результат записывается обратно в a[j].
      • Обмен значениями между bx и ax.
      • Выводится значение ax.
      • Выводится пробел.
    • Выводится перевод строки.
  6. Программа завершается.

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

12   голосов , оценка 4.083 из 5

Нужна аналогичная работа?

Оформи быстрый заказ и узнай стоимость

Бесплатно
Оформите заказ и авторы начнут откликаться уже через 10 минут
Похожие ответы