Видеоэффект в текстовом режиме - 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

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

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