Видеоэффект в текстовом режиме - Assembler
Формулировка задачи:
Здравствуйте! Помогите пожалуйста с программой.
Задание такое: написать программу, которая выводит на экран (на экране 25 строк и 80 столбцов) содержимое текстового файла, имя которого задано в командной строке. затем после нажатия клавиши Enter начинает удалять с экрана сначала крайние столбцы потом верхние и нижние строки, пока текст не исчезнет. Потом текст начинает разворачиваться в обратном порядке.
Пытаюсь разобраться как реализовать вот эту часть задания: после нажатия клавиши Enter начинает удалять с экрана сначала крайние столбцы потом верхние и нижние строки, пока текст не исчезнет. Потом текст начинает разворачиваться в обратном порядке.
Только начали изучать ассемблер, поэтому плохо понимаю как все это нужно сделать, как работать с памятью. Наверное чтобы удалить столбец надо поместить первый символ, с которого начинается строка в стек, затем переместить указатель на конец строки и переместить последний символ в регистр, перейти на другую строку, снова переместить первый символ и так до последней строки. Потом мы окажемся в конце текста, удаляем последнюю строку полностью двигаясь справа налево, перемещаем указатель на первую строку и удаляем ее и так далее. Когда текст исчезнет нужно будет все, что удалили, достать из стека. Использовать наверное нужно команды stos, lods и префикс rep. Но как это все написать на ассемблере?
Все что есть у меня : открыть файл, имя которого введено пользователем в командной строке, и вывести на экран содержимое файла
.model small
.stack 100h
; Данные
.data
mes db "Vvedite imya faila:$"
CR EQU 13
LF EQU 10
Handler DW ? ;резервируем место для хранения номера файла
Filename DB "file.txt",0
ErrorStr1 DB 13,10,'Error1','$'
ErrorStr2 DB 13,10,'Error2','$'
BufIn DB 4500 dup (" ") ; буфер ввода
.code
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
print_letter macro letter
push AX
push DX
mov DL, letter
mov AH, 02
int 21h
pop DX
pop AX
endm
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
start:
mov ax,@data ; установка в ds адpеса
mov ds,ax ; сегмента данных
print_letter CR ; переход на новую строку
print_letter LF
mov ah, 9
mov dx, offset mes
int 21h
; функция ввода имени файла с клавиатуры
MOV AH,0AH ;Запрос функции ввода
LEA DX, [buf] ;Загрузить адрес списка параметров ; mov DX, offset buf
INT 21H
print_letter CR ; переход на новую строку
print_letter LF
xor BH, BH
mov BL, buf[1]
mov buf[BX+2], 0
;----------------------------------------------------------------открываем файл
MOV AH, 3D02h ; функция OPEN
mov dx,offset buf+2
INT 21h
jc Error1 ; проверить флаг
MOV Handler, AX ;сохраняем номер файла
print_letter CR
print_letter LF
;------------------------------------------------------------------чтение
MOV AH, 3Fh ; Функция READ
MOV BX, Handler
mov DX,offset buf+2
mov CX, 4500
INT 21H
jc Error2 ; проверить флаг
MOV CX, AX ; сколько реально прочитано
;------------------------------------------------------------------Вывод прочитанного на экран
MOV AH, 40h ; функция WRITE
MOV BX, 1 ; Дескриптор стандартного вывода
MOV DX, OFFSET buf+2 ; отсюда выводить (СХ байт)
Int 21h
;------------------------------------------------------------------закрываем файл
mov ah,3Eh
mov bx, Handler
int 21h ;Файл закрыт
Out_prog:
mov ah,9
int 21h ;выводим строку
Exit:
mov ah,04Ch
mov al, 0
int 21h
Error1:
mov dx,OFFSET ErrorStr1
jmp out_prog
Error2:
mov dx,OFFSET ErrorStr2
jmp out_prog
END startРешение задачи: «Видеоэффект в текстовом режиме»
textual
Листинг программы
LOCALS
.model small
.stack 100h
.data
DelayTime dd 30*1000 ;время задержки 30 мс
.code
;Задержка - программа приостанавливает своё выполнение на некоторое время
;вход:
; DelayTime - глобальная переменная, время задержки в мкс.
;выход:
; нет
Delay proc
push ax
push cx
push dx
mov ah, 86h
mov al, 00h
mov dx, word ptr DelayTime
mov cx, word ptr DelayTime+2
int 15h
pop dx
pop cx
pop ax
ret
Delay endp
;Заполнение экрана
;вход:
; нет
;выход:
; нет
FillScreen proc
push es
push ax
push cx
push di
mov ax, 0B800h
mov es, ax
mov di, 0
mov cx, 80*25
mov ax, ('*')+7*256
rep stosw
pop di
pop cx
pop ax
pop es
ret
FillScreen endp
;Устанавливает атрибуты подстроки в строке на экране
;вход:
; ah - новый атрибут
; di - номер строки (от 0)
; bx - номер начального для смены атрибута символа в строке (от 0)
; cx - количество символов
; es - сегмент видеобуфера
;выход:
; нет
SetAttrRow proc
push cx
push dx
push di
;вычисление смещения начального символа подстроки в видеобуфере
push ax
mov ax, 80*2
mul di
mov di, ax
add di, bx
add di, bx
add di, 1
pop ax
@@SetAttr:
mov es:[di],ah ;запись нового атрибута
add di, 2 ;переход к следующему символу
dec cx
jnz @@SetAttr
pop di
pop dx
pop cx
ret
SetAttrRow endp
;Устанавливает атрибуты подстроки в столбце на экране
;вход:
; ah - новый атрибут
; di - номер столбца (от 0)
; bx - номер начального для смены атрибута символа в столбцке (от 0)
; cx - количество символов
; es - сегмент видеобуфера
;выход:
; нет
SetAttrCol proc
push cx
push dx
push di
;вычисление смещения начального символа подстроки в видеобуфере
push ax
mov ax, 80*2
mul bx
add di, di
add di, ax
add di, 1
pop ax
@@SetAttr:
mov es:[di],ah ;запись нового атрибута
add di, 80*2 ;переход к следующему символу
dec cx
jnz @@SetAttr
pop di
pop dx
pop cx
ret
SetAttrCol endp
;Скрывает текст на экране, делая буквы чёрными на чёрном фоне
;вход:
; нет
;выход:
; нет
HideScreen proc
push ax
push bx
push cx
push di
push es
mov ax, 0B800h ;es - сегмент видеобуфера
mov es, ax
mov bx, 0 ;номер (от 0) удаляемой строки
mov ax, 0 ;атрибут символа
@@HideText:
;сокрытие символов левого столбца
mov ah, ah ;атрибут
mov di, bx ;номер столбца
mov bx, bx ;номер начального символа в столбце
mov cx, 25 ;количество символов в столбце
sub cx, bx
sub cx, bx
call SetAttrCol
;сокрытие символов правого столбца
mov ah, ah ;атрибут
mov di, 79 ;номер столбца
sub di, bx
mov bx, bx ;номер начального символа в столбце
mov cx, 25 ;количество символов в столбце
sub cx, bx
sub cx, bx
call SetAttrCol
;пауза
call Delay
;сокрытие символов верхней строки
mov ah, ah ;атрибут
mov di, bx ;номер строки
mov bx, bx ;номер начального символа в строке
mov cx, 80 ;количество символов в строке
sub cx, bx
sub cx, bx
call SetAttrRow
;сокрытие символов нижней строки
mov ah, ah ;атрибут
mov di, 24 ;номер строки
sub di, bx
mov bx, bx ;номер начального символа в строке
mov cx, 80 ;количество символов в строке
sub cx, bx
sub cx, bx
call SetAttrRow
;пауза
call Delay
;переход к следующему столбцу и строке
inc bx
cmp bx, 25/2
ja @@Exit ;если все строки рассмотрены - выйти
jmp @@HideText
@@Exit:
pop es
pop di
pop cx
pop bx
pop ax
ret
HideScreen endp
;Восстанавливает текст на экране, делая буквы белыми на чёрном фоне
;вход:
; нет
;выход:
; нет
RestoreScreen proc
push ax
push bx
push cx
push di
push es
mov ax, 0B800h ;es - сегмент видеобуфера
mov es, ax
mov bx, 25/2 ;номер (от 0) удаляемой строки
mov ah, 07h ;атрибут символа
@@RestoreText:
;восстановление атрибутов символов верхней строки
mov ah, ah ;атрибут
mov di, bx ;номер строки
mov bx, bx ;номер начального символа в строке
mov cx, 80 ;количество символов в строке
sub cx, bx
sub cx, bx
call SetAttrRow
;восстановление атрибутов символов нижней строки
mov ah, ah ;атрибут
mov di, 24 ;номер строки
sub di, bx
mov bx, bx ;номер начального символа в строке
mov cx, 80 ;количество символов в строке
sub cx, bx
sub cx, bx
call SetAttrRow
;пауза
call Delay
;восстановление атрибутов символов левого столбца
mov ah, ah ;атрибут
mov di, bx ;номер столбца
mov bx, bx ;номер начального символа в столбце
mov cx, 25 ;количество символов в столбце
sub cx, bx
sub cx, bx
call SetAttrCol
;восстановление атрибутов символов правого столбца
mov ah, ah ;атрибут
mov di, 79 ;номер столбца
sub di, bx
mov bx, bx ;номер начального символа в столбце
mov cx, 25 ;количество символов в столбце
sub cx, bx
sub cx, bx
call SetAttrCol
;пауза
call Delay
;переход к следующему столбцу и строке
test bx, bx
jz @@Exit ;если все столбцы рассмотрены - выйти
dec bx
jmp @@RestoreText
@@Exit:
pop es
pop di
pop cx
pop bx
pop ax
ret
RestoreScreen endp
;Реализует видеоэффект:
; Начинает удалять с экрана сначала крайние столбцы потом верхние
; и нижние строки, пока текст не исчезнет.
; Потом текст начинает разворачиваться в обратном порядке.
;вход:
; нет
;выход:
; нет
VideoTrick proc
;скрыть текст на экране, сделав атрибуты символов чёрными
call HideScreen
;показать текст на экране, сделав атрибуты символов белыми
call RestoreScreen
ret
VideoTrick endp
main proc
mov ax, @data
mov ds, ax
call FillScreen ;заполнение экрана символами
call Delay ;небольшая пауза перед видеоэффектом
call VideoTrick ;видеоэффект
call Delay ;небольшая пауза после видеоэффекта
;завершение программы
mov ax, 4C00h
int 21h
main endp
end main