[TASM] Магический квадрат (3х3) - Assembler

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

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

Здравствуйте! Надеюсь на вашу помощь. Недавно начал изучать Ассемблер и решил написать программу "Магический квадрат", которая должна вывести все 8 квадратов. Написал несколько строк, но не могу понять где ошибся. Программа входит в вечный цикл...
.model medium
.stack 100h
.386
.data
first dw 0
second dw 0
third dw 0
fourth dw 0
a1 dw 0
a2 dw 0
a3 dw 0
b1 dw 0
b2 dw 5
b3 dw 0
c1 dw 0
c2 dw 0
c3 dw 0
n15 dw 15
n10 dw 10
n9 dw 9
n8 dw 8
n7 dw 7
n6 dw 6
.code
mov ax, @data
mov ds, ax

;-----------------------------------------------
magic_square:
    mov bx, n9
    F:    
    mov a1, bx
    mov first, bx
    
    cmp bx, b2
    JNE Intersect4
    JMP Fall_F
                    Intersect4:
                    mov cx, n9
                    S:
                    mov a2, cx
                    mov second, cx    
                
                    cmp cx, b2
                    JNE Intersect3
                    JMP Fall_S
        
                                Intersect3:
                                mov dx, n9
                                Th: 
                                mov a3, dx
                                mov third, dx
                                
                                cmp dx, b2
                                JNE Intersect2
                                JMP Fall_Th   
                                              
                                              Intersect2:
                                              mov ax, n9
                                              Fh:
                                              mov b1, ax
                                              mov fourth, ax
                                             ; mov ax, b1
                                              cmp ax, b2
                                              JNE Intersect
                                              JMP Fall_Fh
            
                                              Intersect:
                                              cmp ax, a1
                                              JNE Step1
                                              JE Prijok1
                                              Step1:
                                              cmp ax, a2
                                              JNE Step2
                                              JE Prijok1
                                              Step2:
                                              cmp ax, a3
                                              ;JE Fall_Fh

                                              JNE Next1
                                              Prijok1: JMP Fall_Fh
                                              
                                              Next1:
                                              mov ax, a3
                                              cmp ax, a1
                                              JNE Step3
                                              JE Prijok2
                                              Step3:
                                              cmp ax, a2
                                             ; JE Fall_Th
                                              
                                              JNE Next2
                                              Prijok2: JMP Fall_Th
                                              
                                              Next2:
                                              mov ax, a2
                                              cmp ax, a1
                                              ;JE Fall_S
                                              
                                              JNE Next3
                                              JMP Fall_S
                                              Next3:
                                              mov ax, n10
                                              sub ax, a1
                                              mov c3, ax
                                              
                                              mov ax, n10
                                              sub ax, a2
                                              mov c2, ax
                                              
                                              mov ax, n10
                                              sub ax, a3
                                              mov c1, ax
                                              
                                              mov ax, n10
                                              sub ax, b1
                                              mov b3, ax
                                              
                                              mov ax, a1
                                              add ax, b1
                                              add ax, c1
                                              cmp ax, n15
                                              JE Go
                                              JMP Fall_Fh
                                              
                                              Go:
                                              mov ax, a1
                                              add ax, a2
                                              add ax, a3
                                              cmp ax, n15
                                              JE Goo
                                              JMP Fall_Fh
                                              
                                              Goo:
                                              mov ax, a3
                                              add ax, b3
                                              add ax, c3
                                              cmp ax, n15
                                              JE Gooo
                                              JMP Fall_Fh
                                              
                                              Gooo:
                                              mov ax, a1
                                              add ax, b2
                                              add ax, c3
                                              cmp ax, n15
                                              JE Goooo
                                              JMP Fall_Fh
                                              
                                              Goooo:
                                              mov ax, a3
                                              add ax, b2
                                              add ax, c1
                                              cmp ax, n15
                                              JE Print_square
                                              JMP Fall_Fh

                                              mov ax, fourth
                                              Fall_Fh: dec ax
                                              cmp ax, 0
                                              JNE Jumper
                                              JMP Fall_Th
                                              Jumper:
                                              JMP Fh 

                                mov dx, third
                                Fall_Th: dec dx
                                cmp dx, 0
                                JNE Jumper2
                                JMP Fall_S
                                Jumper2:
                                JMP Th

                    mov cx, second
                    Fall_S: dec cx
                    cmp cx, 0
                    JNE Jumper3
                    JMP Fall_F
                    Jumper3:
                    JMP S

    mov bx, first
    Fall_F: dec bx
    cmp bx, 0
    JNE Jumper4
    JMP Konec
    Jumper4:
    JMP F

;------------------------------------------------------------
draw_number:
    push ax
    
    mov dl,0BAh         ;Вертикальная линия
    int 21h
    mov dx,a1        ; Первое число
    int 21h
    mov dl,0BAh         ;Вертикальная линия
    int 21h
    mov dx,a2        ; Второе число
    int 21h
    mov dl,0BAh         ;Вертикальная линия
    int 21h
    mov dx,a3       ; Третье число
    int 21h
    mov dl,0BAh         ;Вертикальная линия
    int 21h
        call print_endline  ;Вызов процедуры вывода конца строки
        call print_msg2
    mov dl,0BAh         ;Вертикальная линия
    int 21h
    mov dx,b1        ; Первое число
    int 21h
    mov dl,0BAh         ;Вертикальная линия
    int 21h
    mov dx,b2        ; Второе число
    ADD dx, 30h    ;------------------------------------------------------------------
    int 21h
    mov dl,0BAh         ;Вертикальная линия
    int 21h
    mov dx,b3       ; Третье число
    int 21h
    mov dl,0BAh         ;Вертикальная линия
    int 21h
        call print_endline  ;Вызов процедуры вывода конца строки
        call print_msg2
    mov dl,0BAh         ;Вертикальная линия
    int 21h
    mov dx,c1        ; Первое число
    int 21h
    mov dl,0BAh         ;Вертикальная линия
    int 21h
    mov dx,c2        ; Второе число
    int 21h
    mov dl,0BAh         ;Вертикальная линия
    int 21h
    mov dx,c3       ; Третье число
    int 21h
    mov dl,0BAh         ;Вертикальная линия
    int 21h 
        call print_endline  ;Вызов процедуры вывода конца строки
 
    pop ax
    
    ret
        
;--------------------------------------------------------------------
print_msg1:
    push ax             ;Сохранение регистров
    push cx
    push dx
 
    mov ax, 3
    mov cx,ax           ;Копируем длину строки в CX
 
    mov ah,2            ;Функция DOS 02h - вывод символа
    mov dl,0DAh         ;Левый верхний угол
    int 21h
    
    mov ah,2            ;Функция DOS 02h - вывод символа
    mov dl,0C4h         ;Горизонтальная линия
    int 21h
    
    mov ah,2            ;Функция DOS 02h - вывод символа
    mov dl,0CBh         ;203
    int 21h
 
    mov ah,2            ;Функция DOS 02h - вывод символа
    mov dl,0C4h         ;Горизонтальная линия
    int 21h
   
    mov ah,2            ;Функция DOS 02h - вывод символа
    mov dl,0CBh         ;203
    int 21h
  
    mov ah,2            ;Функция DOS 02h - вывод символа
    mov dl,0C4h         ;Горизонтальная линия
    int 21h
    
    mov ah,2            ;Функция DOS 02h - вывод символа
    mov dl,0BFh         ;Правый верхний угол
    int 21h
      call print_endline  ;Вызов процедуры вывода конца строки
 
 ;------------------------------------------------------------------------
 
print_msg2:
    push ax             ;Сохранение регистров
    push cx
    push dx
 
    mov ax, 3
    mov cx,ax           ;Копируем длину строки в CX
    
mov ah,2 
    mov dl,0CCh         ;left cross
    int 21h
 
mov ah,2    
 mov dl,0C4h         ;Горизонтальная линия
    int 21h
   
mov ah,2 
 mov dl,0CEh         ;cross
    int 21h
  
mov ah,2 
  mov dl,0C4h         ;Горизонтальная линия
    int 21h
    
mov ah,2 
mov dl,0CEh         ;cross
    int 21h
 
mov ah,2     
mov dl,0C4h         ;Горизонтальная линия
    int 21h
   
mov ah,2 
mov dl,0B9h         ;right cross
    int 21h
        call print_endline  ;Вызов процедуры вывода конца строки
 
    pop dx              ;Восстановление регистров
    pop cx
    pop ax
    ret                 ;Возврат из процедуры
 
;-------------------------------------------------------
 
print_msg3:
    push ax             ;Сохранение регистров
    push cx
    push dx
 
    mov ax, 3
    mov cx,ax           ;Копируем длину строки в CX
   
 mov ah,2            ;Функция DOS 02h - вывод символа
    mov dl,0C8h         ;Левый нижний угол
    int 21h
mov ah,2            ;Функция DOS 02h - вывод символа    
mov dl,0C4h         ;Горизонтальная линия
    int 21h
mov ah,2            ;Функция DOS 02h - вывод символа    
mov dl,0CAh         ;cross up
    int 21h
mov ah,2            ;Функция DOS 02h - вывод символа    
mov dl,0C4h         ;Горизонтальная линия
    int 21h
mov ah,2            ;Функция DOS 02h - вывод символа    
mov dl,0CAh         ;cross up
    int 21h
mov ah,2            ;Функция DOS 02h - вывод символа    
mov dl,0C4h         ;Горизонтальная линия
    int 21h
mov ah,2            ;Функция DOS 02h - вывод символа   
mov dl,06Ch         ; sub right cross
    int 21h
    call print_endline  ;Вызов процедуры вывода конца строки
 
    pop dx              ;Восстановление регистров
    pop cx
    pop ax
    ret                 ;Возврат из процедуры
 
;----------------------------------------------------------------------
    
print_endline:
    push ax             ;Сохранение регистров
    push dx
    mov ah,2            ;Функция DOS 02h - вывод символа
    mov dl,13           ;Символ CR
    int 21h
    mov dl,10           ;Символ LF
    int 21h
    pop dx              ;Восстановление регистров
    pop ax
    ret                 ;Возврат из процедуры
    
Konec:
Print_square:
    call print_msg1
    call draw_number
    call print_msg3
 
    mov ax, 4c00h
    int 21h
    end

Решение задачи: «[TASM] Магический квадрат (3х3)»

textual
Листинг программы
.model small
.stack 100h
.data
Mas db 1,2,3,4,5,6,7,8,9 ; инициализация
 
.code
start:
mov ax,@data
mov ds,ax
call PrintMas  ; вывод исходного массива
xor ah,ah
int 16h
 M:            ; цикл перестановок
 call Change   ; перестановка
 call PrintMas ; вывод
 xor ah,ah     ; ожидание нажатия клавиши
 int 16h
 jnc M         ; все перестановки завершены - выход   
mov ax, 4c00h
int 21h
 
; подпрограмма перестановки
Change:
std
lea si,Mas[7]
mov cx,8
xor dx,dx      ; поиск нарушения порядка элементов
 Scan:
 lodsw
 inc dx
 cmp al,ah
 jb NewMas
 inc si
 loop Scan
stc            ; все элементы по убыванию - выход с флагом
ret
NewMas:
mov di,si
add di,2
lea si,Mas[8]
mov cx,dx
FindMin:       ; поиск второго элемента для обмена
 lodsb
 cmp al,[di]
 ja Exchange
 loop FindMin
Exchange:      ; обмен элементов
xchg al,[di]
mov [si+1],al
lea si,Mas[8]
inc di
 Reverse:      ; реверсирование элементов после обмена
 cmp di,si
 jae FinChange
 lodsb
 xchg al,[di]
 mov [si+1],al
 inc di
 loop Reverse
FinChange:
clc            ; выход без флага
ret
 
; процедура вывода массива
PrintMas:
lea si,Mas
mov cx,9
mov ah,2
 Digit:
 mov dl,[si]
 add dl,30h
 int 21h
 inc si
 loop Digit
mov dl,13
int 21h
mov dl,10
int 21h
ret
end

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

  1. Объявляются секции модели и стека программы.
  2. Объявляется секция данных, где инициализируется массив Mas со значениями 1, 2, 3, 4, 5, 6, 7, 8, 9.
  3. Объявляется секция кода, где начинается программа с метки start.
  4. Загружается адрес сегмента данных в регистр ax, который затем с помощью mov помещается в регистр ds.
  5. Вызывается подпрограмма PrintMas для вывода исходного массива.
  6. Устанавливается значение ah в 0 с помощью операции xor.
  7. Совершается прерывание int 16h для ожидания нажатия клавиши.
  8. Выполняется цикл M для перестановок.
  9. Вызывается подпрограмма Change для выполнения перестановки.
  10. Вызывается подпрограмма PrintMas для вывода переставленного массива.
  11. Ожидается нажатие клавиши с помощью прерывания int 16h.
  12. Если флаг не установлен (клавиша нажата), переходим к метке M для продолжения цикла перестановок.
  13. Если все перестановки завершены, выполняется инструкция mov ax, 4c00h для завершения программы с помощью прерывания int 21h.
  14. Следует подпрограмма Change для выполнения перестановки.
  15. Устанавливается флаг stc.
  16. Загружается адрес элемента Mas[7] в регистр si.
  17. Загружается количество элементов в регистр cx.
  18. Инициализируется регистр dx с помощью xor для поиска нарушения порядка элементов.
  19. Идет сканирование элементов массива.
  20. Загружается очередной элемент в al.
  21. Увеличивается значение dx.
  22. Сравниваются значения al и ah.
  23. Если al меньше ah, переходим к метке NewMas.
  24. Иначе увеличивается значение si и выполняется проверка оставшихся элементов цикла Scan.
  25. Если все элементы упорядочены по убыванию, устанавливается флаг stc и происходит возврат из подпрограммы.
  26. В противном случае, ищется второй элемент для обмена.
  27. Загружается следующий элемент массива в al.
  28. Сравнивается значение al с текущим элементом Mas[di].
  29. Если al больше, переходим к метке Exchange.
  30. Если необходимо, продолжается поиск второго элемента для обмена.
  31. Выполняется обмен элементов al и Mas[di].
  32. Сохраняется значение al в Mas[si+1].
  33. Обновляется адрес элемента si для поиска следующего элемента.
  34. Увеличивается значение di для поиска следующего элемента.
  35. Выполняется реверсирование элементов после обмена.
  36. Сравнивается значение регистра di с si.
  37. Если di больше si, выполняется обратный обмен элементов и обновляются значения регистров.
  38. Продолжается реверсирование элементов до тех пор, пока не все элементы не будут обработаны.
  39. Выполняется завершающая часть подпрограммы с очисткой флага clc и возвратом из подпрограммы.
  40. Происходит подпрограмма PrintMas для вывода массива.
  41. Загружается адрес массива Mas в регистр si.
  42. Загружается количество элементов массива в регистр cx.
  43. Устанавливается значение ah в 2 для выполнения прерывания int 21h.
  44. Выводится значение текущего элемента массива, увеличивается значение si и продолжается цикл Digit до вывода всех элементов.
  45. Выводится символ перевода строки и возврата каретки.
  46. Происходит возврат из подпрограммы.
  47. Программа завершается.

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

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