Изменить программу, чтобы символ "рожица" двигался в обратном направлении - Assembler

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

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

Помогите! Нужно изменить программу ниже,чтобы символ "рожица", как только достигнул конца экрана, двигался обратно, и достигнув другого конца экрана закончил программу
Листинг программы
  1. ; Макроопределение задержки на заданное время
  2. delay macro minutes,seconds,hundr
  3. local secs,mins,hrs,check,quit
  4. push_regs <ax,bx,cx,dx>; сохранить регистры
  5. read_time ; считать текущее время
  6. mov ah,ch ; скопировать часы в АН,
  7. mov al,cl ; минуты АL,
  8. mov bh,dh ; секунды BH,
  9. mov bl,dl ; сотые доли BL
  10. ; получить время конца паузы, добавляя значения
  11. ; входных параметров к текущему времени
  12. ifnb <minutes>
  13. add al,minutes
  14. endif
  15. ifnb <seconds>
  16. add bh,seconds
  17. endif
  18. ifnb <hundr>
  19. add bl,hundr
  20. endif
  21. ; учесть возможные переносы
  22. cmp bl,100
  23. jb secs
  24. sub bl,100
  25. inc bh
  26. secs: cmp bh,60
  27. jb mins
  28. sub bh,60
  29. inc al
  30. mins: cmp al,60
  31. jb hrs
  32. sub al,60
  33. inc ah
  34. hrs: cmp ah,24
  35. jne check
  36. sub ah,ah
  37. ; ждать наступления полученного времени считыванием
  38. ; текущего времени и сравнением с полученным
  39. check: read_time
  40. cmp cx,ax
  41. ja quit
  42. jb check
  43. cmp dx,bx
  44. jb check
  45. quit: pop_regs <dx,cx,bx,ax> ; восстановить
  46. endm ; значения регистров
  47. ; Макроопределение занесения регистров в стек
  48. заданном порядке
  49. push_regs macro reg_list
  50. irp reg,<reg_list>
  51. push reg
  52. endm
  53. endm
  54. ; Макроопределение восстановления регистров
  55. ; из стека в заданном порядке
  56. pop_regs macro reg_list
  57. irp reg,<reg_list>
  58. pop reg
  59. endm
  60. endm
  61. ; Макроопределение получения в AL случайного числа
  62. промежутке 0 - lim, где lim=4-127
  63. rand macro lim
  64. local strip
  65. push_regs <cx,dx,ax>; сохранить значения
  66. ; регистров
  67. mov ax,0 ; считать показания таймера
  68. int 1ah
  69. mov ax,dx; поместить младшую часть в АХ
  70. mov cl,lim ; поместить lim и CL
  71. ; удалить из делимого (АХ) достаточное число
  72. ; старших битов, чтобы гарантировать отсутствие
  73. ; переполнения
  74. mov dh,3fh; поместить в DH маску
  75. ; для операции AND
  76. cmp cl,64
  77. jae strip
  78. shr dh,1 ; если lim<64, удалить 3 бита
  79. cmp cl,32
  80. jae strip
  81. shr dh,1 ; если lim<32, удалить 4 бита
  82. cmp cl,16
  83. jae strip
  84. shr dh,1 ; если lim<16, удалить 5 бит
  85. cmp cl,0
  86. jae strip
  87. shr dh,1 ; если lim<8, удалить 6 бит
  88. shr dh,1
  89. strip: and ah,dh ; удалить биты
  90. div cl ; разделить результат в АХ
  91. ; на lim в CL
  92. mov al,ah; поместить остаток в АL
  93. pop cx ; восстановить значения
  94. mov ah,ch; регистров
  95. pop_regs <dx,cx>
  96. endm
  97. ; Макроопределение чтения текущего времени
  98. ;(CH - часы, CL - минуты, DH - секунды, DL сотые
  99. ; доли секунды)
  100. read_time macro
  101. push ax
  102. mov ah,2ch; выбрать режим чтения
  103. ; времени
  104. int 21h ; считать время
  105. pop ax
  106. endm
  107. ; Начало программы
  108. code segment
  109. assume cs:code
  110. start: push_regs <ax,bx,cx,dx> ; сохранить
  111. ;значения регистров
  112. mov ah,15 ; загрузить в ВН номер
  113. int 10h ; активной страницы экрана
  114. mov al, 2
  115. mov ah,0 ; задать текстовый
  116. int 10h ; черно-белый режим 80*25
  117. mov cx,1 ; установить счетчик символов
  118. mov dl,0 ; установить столбец 0
  119. rand 24 ; выбрать строку через генератор
  120. mov dh,al ; случайных чисел
  121. crsr: mov ah,2 ;установить позицию курсора
  122. int 10h
  123. mov al,2 ; задать символ - "рожицу"
  124. mov ah,10 ; вывести символ на экран
  125. int 10h
  126. delay , ,12 ; выдержать паузу
  127. sub al,al ; стереть "рожицу"
  128. mov ah,10
  129. int 10h
  130. inc dl ; выбрать следующую позицию
  131. cmp dl,80 ; в столбце и выйти, если
  132. je ext ; он равен 80
  133. cmp dh,0 ; проверить не установлены ли
  134. je ext ; граничные значения строки
  135. cmp dh,24 ; и если да, то выйти
  136. je ext
  137. rand 60 ; используя генератор случайных
  138. cmp al,20 ; чисел, выбрать направление
  139. jbe zero ; движения "рожицы": вверх,
  140. cmp al,40 ; вниз, вперед
  141. jbe one
  142. jmp crsr
  143. zero: inc dh ; двигаться вниз
  144. jmp crsr
  145. one: dec dh ; двигаться вверх
  146. jmp crsr
  147. ext: pop_regs <dx,cx,bx,ax> ; восстановить
  148. ;регистры
  149. mov ah,4ch ; выйти в DOS
  150. int 21h
  151. code ends
  152. end start

Решение задачи: «Изменить программу, чтобы символ "рожица" двигался в обратном направлении»

textual
Листинг программы
  1. org 256
  2. mov  ax,3
  3. int  10h                         ;устанавливаем текстовый видеорежим 80x25
  4. les  di,[videomem]               ;загружаем в es:di адрес видеопамяти 0B800h:0000
  5. push di
  6. pop  ds                          ;обнуляем ds - из этого сегмента будем считывать счётчик тиков
  7. start:mov  ax,0702h               ax серая рожица на чёрном фоне
  8.       mov  cx,79
  9.       main:stosw                 ;рисуем рожицу
  10.            
  11.            mov ebx,[46Ch]        ;ждём 55 мс - это один тик
  12.            inc ebx              
  13.            @@:cmp ebx,[46Ch]
  14.            ja @b
  15.  
  16.            mov byte[es:di-2],' ' ;стираем рожицу
  17.            mov byte[es:di+2],' '
  18.       loop main
  19.       pushf
  20.       pop  ax
  21.       std                        ;устанавливаем обратное направление рожицы
  22.       test ax,10000000000b       ;если обратное направление уже было - выход из программы
  23. jz start
  24. ret
  25. videomem dd 0B8000000h

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

Список элементов:

  1. org 256 - начало программы, загрузка сегмента данных
  2. mov ax,3 - установка текстового видеорежима 80x25
  3. les di,[videomem] - загрузка в es:di адреса видеопамяти 0B800h:0000
  4. push di - сохранение es:di в стеке
  5. pop ds - восстановление ds из стека
  6. mov ax,0702h - подготовка рожицы (серая рожица на чёрном фоне)
  7. mov cx,79 - установка счётчика тиков
  8. main: stosw - вывод рожицы
  9. mov ebx,[46Ch] - подготовка к ожиданию 55 мс (это один тик)
  10. inc ebx - увеличение счётчика тиков
  11. cmp ebx,[46Ch] - проверка, достиг ли счётчик 55
  12. ja @b - если счётчик достиг или превысил 55, то переход на строку 9
  13. mov byte[es:di-2],' ' - стирание рожицы
  14. mov byte[es:di+2],' ' - стирание рожицы
  15. loop main - повторение вывода рожицы до окончания счётчика тиков
  16. pushf - сохранение флагов в стеке
  17. pop ax - восстановление ax из стека
  18. std - установка обратного направления рожицы
  19. test ax,10000000000b - проверка, было ли обратное направление установлено
  20. jz start - если обратное направление уже было, то переход на начало программы
  21. ret - выход из программы
  22. videomem dd 0B8000000h - описание сегмента памяти для видеопамяти Код выполняет следующую задачу: он рисует рожицу, которая движется в обратном направлении.

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


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

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

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

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

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

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