Доброго времени суток! Мне нужно реализовать программу, которая выводила бы последовательно цифры от 0 до 9 в одно место экрана. При вводе с клавиатуры какой-либо цифры темп вывода менялся. Значение задержки между выводом очередного символа определяется следующим способом: введённую цифру умножить на 2 в степени 9, это и будет число повторений цикла задержки. Для анализа нажатия клавиши использовать вектор 1Ch. (завершение программы осуществляется при вводе цифры 0) Проблема возникла непосредственно при написании подпрограммы обработки прерывания 1Ch... Вот мои наработки по данной программе:
data segment exit db 0 ;признак завершения программы sym db "0","1","2","3","4","5","6","7","8","9" ;символ, выводимый на экран pos dw 3840 ;позиция начального вывода символа atr db 10 ;атрибут символа(зелёный) old_cs dw ? ;адрес сегмента старого вектора 1Сh old_ip dw ? ;адрес смещения старого вектора 1Ch data ends
code segment assume cs:code, ds:data
New_1Ch proc ;подпрограмма обработки прерывания 1Ch
cln1: mov es:[si], ax inc si inc si loop cln1 pop si pop ax pop cx ret ClnScr endp
Delay proc ;программа задержки push cx xor cx,cx mov cl,9 sal count,cl xor cx,cx mov cx,count d: loop d pop cx ret Delay endp
Out_Sym proc push ax push bx push si mov al,[sym+si] mov ah,atr mov bx,pos call Delay mov es:[bx],ax pop bx pop ax ret Out_Sym endp
;основная программа start: mov ax,data mov ds,ax
mov ax, 4c00h int 21h code ends end start
Конечно и эти подпрограммы требуют доработок... Вобщем, требуется Ваша помощь...
volvo
16.12.2008 3:02
Ну, с процедурами - это ты сам как нибудь додумаешь, вот основа программы: получение символа через $1C, и вывод счетчика на экран:
.model small s_data segment
old_cs dw ? ; для хранения «старого» вектора old_ip dw ? ; прерываний с номером 1Ch
atr db 10 ; атрибут символов (зеленый) msg db '0' ; строка, выводимая на экран
cycles dw ? ; 1*2^9 multCycle dw 2048 ; 512 - очень мало, задержку побольше symbol db '1' ; Символ, нажатый пользователем. В начале = "1" curr db 0 ; Номер символа, который печатается в данный момент Pressed db 1 ; Нажал ли пользователь чего-нибудь?
; Куда будет выводиться символ X equ 40 Y equ 14 s_data ends
; Подменим обработчик push ds ; DS:DX <- Новый обработчик mov dx, offset new_1c mov ax, seg new_1c mov ds, ax mov ah, 25h mov al, 1Ch int 21h ; Установили его pop ds
mov ax, s_data mov es, ax ; ES <- s_data
; основной цикл программы main_loop: cmp Pressed, 0 ; Проверяем, было ли нажатие? je make_delay ; Нет, идем к паузе
; Да, было... Сбрасываем флаг нажатия, и проверяем, ; если нажат "0" - на выход
mov Pressed, 0 cmp symbol, 30h je q
xor ax, ax mov al, symbol sub al, 30h ; Число, введенное пользователем mul multCycle ; Домножаем на коэффициент mov cycles, ax ; И сохраняем в cycles
make_delay: ; У меня ничего не получалось разглядеть, пока я не стал ; повторять эту задержку 3000 раз... Если хочешь - убери этот доп. цикл mov cx, 3000 m2: push cx mov cx, cycles m1: nop loop m1 pop cx loop m2
mov al, curr add al, '0' mov msg[0], al ; Конвертируем curr в символ
xor bh, bh mov ah, 13h ; Функция вывода строки с атрибутом mov al, 0 mov dh, Y mov dl, X lea bp, msg ; ES:BP <- выводимая строка mov cx, 1 ; Длина выводимой строки mov bl, atr int 10h
; это я добавлял для тестирования, ; в каком порядке выводятся символы ; mov ah, 0eh ; mov al, msg[0] ; mov bh, 0 ; int 10h
inc curr cmp curr, 10 ; Дошли до десятки? jne main_loop ; Нет еще
; Да, сбрасываем на 0 mov curr, 0 jmp main_loop
q: ; Восстановливаем все назад push ds
mov dx, old_ip mov ax, old_cs mov ds, ax mov ah, 25h mov al, 1Ch int 21h pop ds
mov ax, 4C00h ; И выходим int 21h s_code ends end start
Rocket
16.12.2008 23:12
Цитата(volvo @ 15.12.2008 23:02)
Ну, с процедурами - это ты сам как нибудь додумаешь, вот основа программы: получение символа через $1C, и вывод счетчика на экран:
Большое спасибо за помощь! У меня возник ряд вопросов: 1) Директива equ. Я так понимаю, что это объявление данных? Какой директиве она эквивалентна? 2)
mov msg[0], al
здесь используется относительно регистровая адресация?т.е. адрес вычисляется как сумма содержимого регистра и смещения... 3)
xor bh, bh mov ah, 13h mov al, 0 mov dh, Y mov dl, X lea bp, msg mov cx, 1 mov bl, atr int 10h
Что за прерывание 10h? Как оно организуется,чему оно эквивалентно? например заменить на на функцию 02h, возможно?...
volvo
16.12.2008 23:49
Цитата(Rocket @ 16.12.2008 18:12)
У меня возник ряд вопросов: 1) Директива equ. Я так понимаю, что это объявление данных? Какой директиве она эквивалентна?
Это не объявление данных, это просто символическая константа:
Цитата
Директива EQU не определяет элемент данных, но определяет значение, которое может быть использовано для подстановки в других командах.
, то есть везде, где компилятор встречает слово X, он заменяет его на 40. Аналог Сишного #define, обычная текстовая подстановка.
Цитата(Rocket @ 16.12.2008 18:12)
2)
mov msg[0], al
здесь используется относительно регистровая адресация? т.е. адрес вычисляется как сумма содержимого регистра и смещения...
Индексная адресация: msg - адрес строки, 0 - смещение.
Цитата(Rocket @ 16.12.2008 18:12)
Что за прерывание 10h? Как оно организуется,чему оно эквивалентно? например заменить на на функцию 02h, возможно?...
Что за машина КамАЗ? Как она движется? Чему эквивалентна?
Что за вопросы, как организуется 10-е прерывание? Так же, как и все остальные... Оно у тебя что, под запретом? Это нигде не указано.
10H - это так называемое видео-прерывание, занимается обслуживанием монитора. Функция 13H выводит строку с атрибутами, вторая функция досовского прерывания выводит строку без атрибутов, цвет ты уже потеряешь... Не надо никогда пытаться все привести к использованию только одного прерывания. Пользоваться надо тем, что подходит по функциональности. Для работы с видеоадаптером надо пользоваться видеопрерыванием. Недавно у меня на одном из форумов спросили, можно ли избавиться от подключения модуля DOS в программе, "он же нужен всего для одной функции, что надо сделать, чтобы и использовать функцию, и не делать Uses DOS?". А когда ему привели ассемблерный вариант этой функции: "Пользуйся, ты хотел избавиться от модуля? Избавляйся", он почему-то решил не рисковать, и модули не отключил...
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.