Изменить программу, чтобы символ "рожица" двигался в обратном направлении - Assembler
Формулировка задачи:
Помогите! Нужно изменить программу ниже,чтобы символ "рожица", как только достигнул конца экрана, двигался обратно, и достигнув другого конца экрана закончил программу
Листинг программы
- ; Макроопределение задержки на заданное время
- delay macro minutes,seconds,hundr
- local secs,mins,hrs,check,quit
- push_regs <ax,bx,cx,dx>; сохранить регистры
- read_time ; считать текущее время
- mov ah,ch ; скопировать часы в АН,
- mov al,cl ; минуты -в АL,
- mov bh,dh ; секунды -в BH,
- mov bl,dl ; сотые доли -в BL
- ; получить время конца паузы, добавляя значения
- ; входных параметров к текущему времени
- ifnb <minutes>
- add al,minutes
- endif
- ifnb <seconds>
- add bh,seconds
- endif
- ifnb <hundr>
- add bl,hundr
- endif
- ; учесть возможные переносы
- cmp bl,100
- jb secs
- sub bl,100
- inc bh
- secs: cmp bh,60
- jb mins
- sub bh,60
- inc al
- mins: cmp al,60
- jb hrs
- sub al,60
- inc ah
- hrs: cmp ah,24
- jne check
- sub ah,ah
- ; ждать наступления полученного времени считыванием
- ; текущего времени и сравнением с полученным
- check: read_time
- cmp cx,ax
- ja quit
- jb check
- cmp dx,bx
- jb check
- quit: pop_regs <dx,cx,bx,ax> ; восстановить
- endm ; значения регистров
- ; Макроопределение занесения регистров в стек
- ;в заданном порядке
- push_regs macro reg_list
- irp reg,<reg_list>
- push reg
- endm
- endm
- ; Макроопределение восстановления регистров
- ; из стека в заданном порядке
- pop_regs macro reg_list
- irp reg,<reg_list>
- pop reg
- endm
- endm
- ; Макроопределение получения в AL случайного числа
- ;в промежутке 0 - lim, где lim=4-127
- rand macro lim
- local strip
- push_regs <cx,dx,ax>; сохранить значения
- ; регистров
- mov ax,0 ; считать показания таймера
- int 1ah
- mov ax,dx; поместить младшую часть в АХ
- mov cl,lim ; поместить lim и CL
- ; удалить из делимого (АХ) достаточное число
- ; старших битов, чтобы гарантировать отсутствие
- ; переполнения
- mov dh,3fh; поместить в DH маску
- ; для операции AND
- cmp cl,64
- jae strip
- shr dh,1 ; если lim<64, удалить 3 бита
- cmp cl,32
- jae strip
- shr dh,1 ; если lim<32, удалить 4 бита
- cmp cl,16
- jae strip
- shr dh,1 ; если lim<16, удалить 5 бит
- cmp cl,0
- jae strip
- shr dh,1 ; если lim<8, удалить 6 бит
- shr dh,1
- strip: and ah,dh ; удалить биты
- div cl ; разделить результат в АХ
- ; на lim в CL
- mov al,ah; поместить остаток в АL
- pop cx ; восстановить значения
- mov ah,ch; регистров
- pop_regs <dx,cx>
- endm
- ; Макроопределение чтения текущего времени
- ;(CH - часы, CL - минуты, DH - секунды, DL – сотые
- ; доли секунды)
- read_time macro
- push ax
- mov ah,2ch; выбрать режим чтения
- ; времени
- int 21h ; считать время
- pop ax
- endm
- ; Начало программы
- code segment
- assume cs:code
- start: push_regs <ax,bx,cx,dx> ; сохранить
- ;значения регистров
- mov ah,15 ; загрузить в ВН номер
- int 10h ; активной страницы экрана
- mov al, 2
- mov ah,0 ; задать текстовый
- int 10h ; черно-белый режим 80*25
- mov cx,1 ; установить счетчик символов
- mov dl,0 ; установить столбец 0
- rand 24 ; выбрать строку через генератор
- mov dh,al ; случайных чисел
- crsr: mov ah,2 ;установить позицию курсора
- int 10h
- mov al,2 ; задать символ - "рожицу"
- mov ah,10 ; вывести символ на экран
- int 10h
- delay , ,12 ; выдержать паузу
- sub al,al ; стереть "рожицу"
- mov ah,10
- int 10h
- inc dl ; выбрать следующую позицию
- cmp dl,80 ; в столбце и выйти, если
- je ext ; он равен 80
- cmp dh,0 ; проверить не установлены ли
- je ext ; граничные значения строки
- cmp dh,24 ; и если да, то выйти
- je ext
- rand 60 ; используя генератор случайных
- cmp al,20 ; чисел, выбрать направление
- jbe zero ; движения "рожицы": вверх,
- cmp al,40 ; вниз, вперед
- jbe one
- jmp crsr
- zero: inc dh ; двигаться вниз
- jmp crsr
- one: dec dh ; двигаться вверх
- jmp crsr
- ext: pop_regs <dx,cx,bx,ax> ; восстановить
- ;регистры
- mov ah,4ch ; выйти в DOS
- int 21h
- code ends
- end start
Решение задачи: «Изменить программу, чтобы символ "рожица" двигался в обратном направлении»
textual
Листинг программы
- org 256
- mov ax,3
- int 10h ;устанавливаем текстовый видеорежим 80x25
- les di,[videomem] ;загружаем в es:di адрес видеопамяти 0B800h:0000
- push di
- pop ds ;обнуляем ds - из этого сегмента будем считывать счётчик тиков
- start:mov ax,0702h ;в ax серая рожица на чёрном фоне
- mov cx,79
- main:stosw ;рисуем рожицу
- mov ebx,[46Ch] ;ждём 55 мс - это один тик
- inc ebx
- @@:cmp ebx,[46Ch]
- ja @b
- mov byte[es:di-2],' ' ;стираем рожицу
- mov byte[es:di+2],' '
- loop main
- pushf
- pop ax
- std ;устанавливаем обратное направление рожицы
- test ax,10000000000b ;если обратное направление уже было - выход из программы
- jz start
- ret
- videomem dd 0B8000000h
Объяснение кода листинга программы
Список элементов:
- org 256 - начало программы, загрузка сегмента данных
- mov ax,3 - установка текстового видеорежима 80x25
- les di,[videomem] - загрузка в es:di адреса видеопамяти 0B800h:0000
- push di - сохранение es:di в стеке
- pop ds - восстановление ds из стека
- mov ax,0702h - подготовка рожицы (серая рожица на чёрном фоне)
- mov cx,79 - установка счётчика тиков
- main: stosw - вывод рожицы
- mov ebx,[46Ch] - подготовка к ожиданию 55 мс (это один тик)
- inc ebx - увеличение счётчика тиков
- cmp ebx,[46Ch] - проверка, достиг ли счётчик 55
- ja @b - если счётчик достиг или превысил 55, то переход на строку 9
- mov byte[es:di-2],' ' - стирание рожицы
- mov byte[es:di+2],' ' - стирание рожицы
- loop main - повторение вывода рожицы до окончания счётчика тиков
- pushf - сохранение флагов в стеке
- pop ax - восстановление ax из стека
- std - установка обратного направления рожицы
- test ax,10000000000b - проверка, было ли обратное направление установлено
- jz start - если обратное направление уже было, то переход на начало программы
- ret - выход из программы
- videomem dd 0B8000000h - описание сегмента памяти для видеопамяти Код выполняет следующую задачу: он рисует рожицу, которая движется в обратном направлении.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д