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

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

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

Здравствуйте! Надеюсь на вашу помощь. Недавно начал изучать Ассемблер и решил написать программу "Магический квадрат", которая должна вывести все 8 квадратов. Написал несколько строк, но не могу понять где ошибся. Программа входит в вечный цикл...
Листинг программы
  1. .model medium
  2. .stack 100h
  3. .386
  4. .data
  5. first dw 0
  6. second dw 0
  7. third dw 0
  8. fourth dw 0
  9. a1 dw 0
  10. a2 dw 0
  11. a3 dw 0
  12. b1 dw 0
  13. b2 dw 5
  14. b3 dw 0
  15. c1 dw 0
  16. c2 dw 0
  17. c3 dw 0
  18. n15 dw 15
  19. n10 dw 10
  20. n9 dw 9
  21. n8 dw 8
  22. n7 dw 7
  23. n6 dw 6
  24. .code
  25. mov ax, @data
  26. mov ds, ax
  27.  
  28. ;-----------------------------------------------
  29. magic_square:
  30. mov bx, n9
  31. F:
  32. mov a1, bx
  33. mov first, bx
  34. cmp bx, b2
  35. JNE Intersect4
  36. JMP Fall_F
  37. Intersect4:
  38. mov cx, n9
  39. S:
  40. mov a2, cx
  41. mov second, cx
  42. cmp cx, b2
  43. JNE Intersect3
  44. JMP Fall_S
  45. Intersect3:
  46. mov dx, n9
  47. Th:
  48. mov a3, dx
  49. mov third, dx
  50. cmp dx, b2
  51. JNE Intersect2
  52. JMP Fall_Th
  53. Intersect2:
  54. mov ax, n9
  55. Fh:
  56. mov b1, ax
  57. mov fourth, ax
  58. ; mov ax, b1
  59. cmp ax, b2
  60. JNE Intersect
  61. JMP Fall_Fh
  62. Intersect:
  63. cmp ax, a1
  64. JNE Step1
  65. JE Prijok1
  66. Step1:
  67. cmp ax, a2
  68. JNE Step2
  69. JE Prijok1
  70. Step2:
  71. cmp ax, a3
  72. ;JE Fall_Fh
  73.  
  74. JNE Next1
  75. Prijok1: JMP Fall_Fh
  76. Next1:
  77. mov ax, a3
  78. cmp ax, a1
  79. JNE Step3
  80. JE Prijok2
  81. Step3:
  82. cmp ax, a2
  83. ; JE Fall_Th
  84. JNE Next2
  85. Prijok2: JMP Fall_Th
  86. Next2:
  87. mov ax, a2
  88. cmp ax, a1
  89. ;JE Fall_S
  90. JNE Next3
  91. JMP Fall_S
  92. Next3:
  93. mov ax, n10
  94. sub ax, a1
  95. mov c3, ax
  96. mov ax, n10
  97. sub ax, a2
  98. mov c2, ax
  99. mov ax, n10
  100. sub ax, a3
  101. mov c1, ax
  102. mov ax, n10
  103. sub ax, b1
  104. mov b3, ax
  105. mov ax, a1
  106. add ax, b1
  107. add ax, c1
  108. cmp ax, n15
  109. JE Go
  110. JMP Fall_Fh
  111. Go:
  112. mov ax, a1
  113. add ax, a2
  114. add ax, a3
  115. cmp ax, n15
  116. JE Goo
  117. JMP Fall_Fh
  118. Goo:
  119. mov ax, a3
  120. add ax, b3
  121. add ax, c3
  122. cmp ax, n15
  123. JE Gooo
  124. JMP Fall_Fh
  125. Gooo:
  126. mov ax, a1
  127. add ax, b2
  128. add ax, c3
  129. cmp ax, n15
  130. JE Goooo
  131. JMP Fall_Fh
  132. Goooo:
  133. mov ax, a3
  134. add ax, b2
  135. add ax, c1
  136. cmp ax, n15
  137. JE Print_square
  138. JMP Fall_Fh
  139.  
  140. mov ax, fourth
  141. Fall_Fh: dec ax
  142. cmp ax, 0
  143. JNE Jumper
  144. JMP Fall_Th
  145. Jumper:
  146. JMP Fh
  147.  
  148. mov dx, third
  149. Fall_Th: dec dx
  150. cmp dx, 0
  151. JNE Jumper2
  152. JMP Fall_S
  153. Jumper2:
  154. JMP Th
  155.  
  156. mov cx, second
  157. Fall_S: dec cx
  158. cmp cx, 0
  159. JNE Jumper3
  160. JMP Fall_F
  161. Jumper3:
  162. JMP S
  163.  
  164. mov bx, first
  165. Fall_F: dec bx
  166. cmp bx, 0
  167. JNE Jumper4
  168. JMP Konec
  169. Jumper4:
  170. JMP F
  171.  
  172. ;------------------------------------------------------------
  173. draw_number:
  174. push ax
  175. mov dl,0BAh ;Вертикальная линия
  176. int 21h
  177. mov dx,a1 ; Первое число
  178. int 21h
  179. mov dl,0BAh ;Вертикальная линия
  180. int 21h
  181. mov dx,a2 ; Второе число
  182. int 21h
  183. mov dl,0BAh ;Вертикальная линия
  184. int 21h
  185. mov dx,a3 ; Третье число
  186. int 21h
  187. mov dl,0BAh ;Вертикальная линия
  188. int 21h
  189. call print_endline ;Вызов процедуры вывода конца строки
  190. call print_msg2
  191. mov dl,0BAh ;Вертикальная линия
  192. int 21h
  193. mov dx,b1 ; Первое число
  194. int 21h
  195. mov dl,0BAh ;Вертикальная линия
  196. int 21h
  197. mov dx,b2 ; Второе число
  198. ADD dx, 30h ;------------------------------------------------------------------
  199. int 21h
  200. mov dl,0BAh ;Вертикальная линия
  201. int 21h
  202. mov dx,b3 ; Третье число
  203. int 21h
  204. mov dl,0BAh ;Вертикальная линия
  205. int 21h
  206. call print_endline ;Вызов процедуры вывода конца строки
  207. call print_msg2
  208. mov dl,0BAh ;Вертикальная линия
  209. int 21h
  210. mov dx,c1 ; Первое число
  211. int 21h
  212. mov dl,0BAh ;Вертикальная линия
  213. int 21h
  214. mov dx,c2 ; Второе число
  215. int 21h
  216. mov dl,0BAh ;Вертикальная линия
  217. int 21h
  218. mov dx,c3 ; Третье число
  219. int 21h
  220. mov dl,0BAh ;Вертикальная линия
  221. int 21h
  222. call print_endline ;Вызов процедуры вывода конца строки
  223. pop ax
  224. ret
  225. ;--------------------------------------------------------------------
  226. print_msg1:
  227. push ax ;Сохранение регистров
  228. push cx
  229. push dx
  230. mov ax, 3
  231. mov cx,ax ;Копируем длину строки в CX
  232. mov ah,2 ;Функция DOS 02h - вывод символа
  233. mov dl,0DAh ;Левый верхний угол
  234. int 21h
  235. mov ah,2 ;Функция DOS 02h - вывод символа
  236. mov dl,0C4h ;Горизонтальная линия
  237. int 21h
  238. mov ah,2 ;Функция DOS 02h - вывод символа
  239. mov dl,0CBh ;203
  240. int 21h
  241. mov ah,2 ;Функция DOS 02h - вывод символа
  242. mov dl,0C4h ;Горизонтальная линия
  243. int 21h
  244. mov ah,2 ;Функция DOS 02h - вывод символа
  245. mov dl,0CBh ;203
  246. int 21h
  247. mov ah,2 ;Функция DOS 02h - вывод символа
  248. mov dl,0C4h ;Горизонтальная линия
  249. int 21h
  250. mov ah,2 ;Функция DOS 02h - вывод символа
  251. mov dl,0BFh ;Правый верхний угол
  252. int 21h
  253. call print_endline ;Вызов процедуры вывода конца строки
  254. ;------------------------------------------------------------------------
  255. print_msg2:
  256. push ax ;Сохранение регистров
  257. push cx
  258. push dx
  259. mov ax, 3
  260. mov cx,ax ;Копируем длину строки в CX
  261. mov ah,2
  262. mov dl,0CCh ;left cross
  263. int 21h
  264. mov ah,2
  265. mov dl,0C4h ;Горизонтальная линия
  266. int 21h
  267. mov ah,2
  268. mov dl,0CEh ;cross
  269. int 21h
  270. mov ah,2
  271. mov dl,0C4h ;Горизонтальная линия
  272. int 21h
  273. mov ah,2
  274. mov dl,0CEh ;cross
  275. int 21h
  276. mov ah,2
  277. mov dl,0C4h ;Горизонтальная линия
  278. int 21h
  279. mov ah,2
  280. mov dl,0B9h ;right cross
  281. int 21h
  282. call print_endline ;Вызов процедуры вывода конца строки
  283. pop dx ;Восстановление регистров
  284. pop cx
  285. pop ax
  286. ret ;Возврат из процедуры
  287. ;-------------------------------------------------------
  288. print_msg3:
  289. push ax ;Сохранение регистров
  290. push cx
  291. push dx
  292. mov ax, 3
  293. mov cx,ax ;Копируем длину строки в CX
  294. mov ah,2 ;Функция DOS 02h - вывод символа
  295. mov dl,0C8h ;Левый нижний угол
  296. int 21h
  297. mov ah,2 ;Функция DOS 02h - вывод символа
  298. mov dl,0C4h ;Горизонтальная линия
  299. int 21h
  300. mov ah,2 ;Функция DOS 02h - вывод символа
  301. mov dl,0CAh ;cross up
  302. int 21h
  303. mov ah,2 ;Функция DOS 02h - вывод символа
  304. mov dl,0C4h ;Горизонтальная линия
  305. int 21h
  306. mov ah,2 ;Функция DOS 02h - вывод символа
  307. mov dl,0CAh ;cross up
  308. int 21h
  309. mov ah,2 ;Функция DOS 02h - вывод символа
  310. mov dl,0C4h ;Горизонтальная линия
  311. int 21h
  312. mov ah,2 ;Функция DOS 02h - вывод символа
  313. mov dl,06Ch ; sub right cross
  314. int 21h
  315. call print_endline ;Вызов процедуры вывода конца строки
  316. pop dx ;Восстановление регистров
  317. pop cx
  318. pop ax
  319. ret ;Возврат из процедуры
  320. ;----------------------------------------------------------------------
  321. print_endline:
  322. push ax ;Сохранение регистров
  323. push dx
  324. mov ah,2 ;Функция DOS 02h - вывод символа
  325. mov dl,13 ;Символ CR
  326. int 21h
  327. mov dl,10 ;Символ LF
  328. int 21h
  329. pop dx ;Восстановление регистров
  330. pop ax
  331. ret ;Возврат из процедуры
  332. Konec:
  333. Print_square:
  334. call print_msg1
  335. call draw_number
  336. call print_msg3
  337. mov ax, 4c00h
  338. int 21h
  339. end

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

textual
Листинг программы
  1. .model small
  2. .stack 100h
  3. .data
  4. Mas db 1,2,3,4,5,6,7,8,9 ; инициализация
  5.  
  6. .code
  7. start:
  8. mov ax,@data
  9. mov ds,ax
  10. call PrintMas  ; вывод исходного массива
  11. xor ah,ah
  12. int 16h
  13.  M:            ; цикл перестановок
  14.  call Change   ; перестановка
  15.  call PrintMas ; вывод
  16.  xor ah,ah     ; ожидание нажатия клавиши
  17.  int 16h
  18.  jnc M         ; все перестановки завершены - выход  
  19. mov ax, 4c00h
  20. int 21h
  21.  
  22. ; подпрограмма перестановки
  23. Change:
  24. std
  25. lea si,Mas[7]
  26. mov cx,8
  27. xor dx,dx      ; поиск нарушения порядка элементов
  28.  Scan:
  29.  lodsw
  30.  inc dx
  31.  cmp al,ah
  32.  jb NewMas
  33.  inc si
  34.  loop Scan
  35. stc            ; все элементы по убыванию - выход с флагом
  36. ret
  37. NewMas:
  38. mov di,si
  39. add di,2
  40. lea si,Mas[8]
  41. mov cx,dx
  42. FindMin:       ; поиск второго элемента для обмена
  43.  lodsb
  44.  cmp al,[di]
  45.  ja Exchange
  46.  loop FindMin
  47. Exchange:      ; обмен элементов
  48. xchg al,[di]
  49. mov [si+1],al
  50. lea si,Mas[8]
  51. inc di
  52.  Reverse:      ; реверсирование элементов после обмена
  53.  cmp di,si
  54.  jae FinChange
  55.  lodsb
  56.  xchg al,[di]
  57.  mov [si+1],al
  58.  inc di
  59.  loop Reverse
  60. FinChange:
  61. clc            ; выход без флага
  62. ret
  63.  
  64. ; процедура вывода массива
  65. PrintMas:
  66. lea si,Mas
  67. mov cx,9
  68. mov ah,2
  69.  Digit:
  70.  mov dl,[si]
  71.  add dl,30h
  72.  int 21h
  73.  inc si
  74.  loop Digit
  75. mov dl,13
  76. int 21h
  77. mov dl,10
  78. int 21h
  79. ret
  80. 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

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

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

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