Заполнить квадратную матрицу по спирали - Assembler

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

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

Cоставить программу, которая заполняет квадратную матрицу порядка n нaтуральными числами 1,2,3,...n,записывая их в нее "по спирали" например, для n=5 получаем матрицу:
 1  2  3  4  5 
16 17 18 19  6
15 24 25 20  7
14 23 22 21  8
13 12 11 10  9

Решение задачи: «Заполнить квадратную матрицу по спирали»

textual
Листинг программы
@stack  segment para stack
        db      1024 dup(?)
@stack  ends
 
@data   segment
        Nmax    equ     10
        N       dw      8
        Matrix  dw      (Nmax*Nmax) dup(?)
 
        CrLf    db      0Dh, 0Ah, '$'
 
        ;переменные для алгоритма заполнения матрицы по спирали
        _N              dw      ?
        _M              dw      ?
        _Row            dw      ?
        _Col            dw      ?
        _dx             dw      ?
        _dy             dw      ?
        _dirChanges     dw      ?
        _visits         dw      ?
        _MLength        dw      ?
 
 
@data   ends
 
@code   segment
        assume  cs:@code, ds:@data, ss:@stack
main    proc
        ;инициализация сегментного регистра данных
        mov     ax,     @data
        mov     ds,     ax
        mov     es,     ax
 
        ;инициализация матрицы
        lea     di,     [Matrix]
        mov     ax,     0
        mov     cx,     (Nmax*Nmax)
        rep     stosw
        ;заполнение матрицы по спирали
        lea     dx,     [Matrix]
        mov     cx,     [N]
        call    FillHelix
        ;вывод матрицы
        lea     dx,     [Matrix]
        mov     bx,     [N]
        mov     cx,     [N]
        call    ShowMatrix
 
        ;завершение программы
        mov     ax,     4C00h
        int 21h
main    endp
 
;Заполнение матрицы по спирали
;на входе:
;  ds:dx - адрес матрицы
;  cx    - размер квадратной матрицы
;на выходе:
;  заполненная по спирали матрица
FillHelix       proc
        push    ax
        push    bx
        push    cx
        push    dx
        push    si
        push    di
 
        or      cx,     cx
        jnz     @@fhStart
        jmp     @@fhExit
@@fhStart:
        mov     bx,     dx      ;bx - адрес начала матрицы
 
        mov     ax,     cx
        mov     [_N],   ax
        mul     ax
        mov     [_MLength],     ax
 
        mov     ax,     0
        mov     [_row], ax      ;    int row = 0;
        mov     [_col], ax      ;    int col = 0;
        mov     ax,     1
        mov     [_dx],  ax      ;    int dx = 1;
        mov     ax,     0
        mov     [_dy],  ax      ;    int dy = 0;
        mov     [_dirChanges],ax;    int dirChanges = 0;
        mov     ax,     cx
        mov     [_M],   ax
        mov     [_visits],ax    ;    int visits = m;
 
        mov     cx,     0       ;    for (int i = 0; i < matrix.Length; i++) {
@@fhFor:
        inc     cx
        mov     ax,     [_row]  ;        matrix[row, col] = i + 1;
        mul     [_M]
        shl     ax,     1
        mov     si,     [_col]
        shl     si,     1
        add     si,     ax
        mov     [bx+si],cx
 
        dec     [_visits]       ;      if (--visits == 0) {
        jnz     @@fhEnd_if
                                ;        visits = m * (dirChanges %2)
        mov     ax,     [_dirChanges]
        and     ax,     1
        mul     [_M]
        mov     si,     ax
                                ;               + n * ((dirChanges + 1) %2)
        mov     ax,     [_dirChanges]
        inc     ax
        and     ax,     1
        mul     [_N]
        add     si,     ax
                                ;               - (dirChanges/2 - 1) - 2;
        mov     ax,     [_dirChanges]
        shr     ax,     1
        dec     ax
        sub     si,     ax
        sub     si,     2
        mov     [_visits],si
 
        mov     si,     [_dx]   ;        int temp = dx;
        mov     ax,     [_dy]   ;        dx = -dy;
        neg     ax
        mov     [_dx],  ax
        mov     [_dy],  si      ;        dy = temp;
        inc     [_dirChanges]   ;        dirChanges++;
                                ;      }
@@fhEnd_if:
        mov     ax,     [_dx]   ;      col += dx;
        add     [_col], ax
        mov     ax,     [_dy]   ;      row += dy;
        add     [_row], ax
 
        cmp     cx,     [_MLength]
        jbe     @@fhFor         ;    }
 
 
@@fhExit:
        pop     di
        pop     si
        pop     dx
        pop     cx
        pop     bx
        pop     ax
        ret
FillHelix       endp
 
;Вывод на экран матрицы слов
;на входе:
;  ds:dx - адрес матрицы
;  bx    - количество столбцов в матрице
;  cx    - количество строк в мматрице
;на входе:
;  -
ShowMatrix      proc
        push    ax
        push    bx
        push    cx
        push    dx
        push    si
        push    di
        pushf
 
        jcxz    @@smExit
        or      bx,     bx
        jz      @@smExit
 
        cld
        mov     cx,     cx
        mov     si,     dx
        @@smForI:
                push    cx
                push    bx
                mov     cx,     bx
                @@smForJ:
                        lodsw
                        call    Show_AX
                loop    @@smForJ
                mov     ah,     09h
                lea     dx,     [CrLf]
                int     21h
                pop     bx
                pop     cx
        loop    @@smForI
 
@@smExit:
        popf
        pop     di
        pop     si
        pop     dx
        pop     cx
        pop     bx
        pop     ax
        ret
ShowMatrix      endp
 
; выводит знаковое 16-разрядное число из регистра AX на экран
; входные данные:
; ax - число для отображения
Show_AX proc
        push    ax
        push    bx
        push    cx
        push    dx
        push    si
        push    di
 
        mov     cx,     10      ;основание системы счисления
        xor     di,     di      ; di - кол. цифр в числе
        xor     si,     si      ; si - признак отрицательного числа
        ; если число в ax отрицательное, то
        ;1) напечатать (запомнить в стеке) символ '-'
        ;2) сделать ax положительным
        or      ax,     ax
        jns     @@Conv
        mov     si,     1
 
        neg     ax
 
@@Conv:
        xor     dx,     dx
        div     cx              ; dl = num mod 10
        add     dl,     '0'     ; перевод в символьный формат
        inc     di
        push    dx              ; складываем в стек
        or      ax,     ax
        jnz     @@Conv
        ;если число отрицательное - помещаем символ "-" в строку
        or      si,     si
        jz      @@Positive
        mov     dx,     '-'
        push    dx
        inc     di
@@Positive:
        ; выводим из стека на экран
        ; - сначала пробелы для выравнивания по правому краю
        mov     cx,     8
        sub     cx,     di
        mov     ah,     02h
        mov     dl,     ' '
@@LeftPad:
        int     21h
        loop    @@LeftPad
        ;сохранённые символы цифр
@@Show:
        pop     dx              ; dl = очередной выводимый символ
        mov     ah,     2       ; ah - функция вывода символа на экран
        int     21h
        dec     di              ; повторяем пока di<>0
        jnz     @@Show
 
        pop     di
        pop     si
        pop     dx
        pop     cx
        pop     bx
        pop     ax
        ret
Show_AX endp
 
@code   ends
 
        end     main

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

5   голосов , оценка 4 из 5
Похожие ответы