1. Заголовок или название темы должно быть информативным 2. Все тексты программ должны помещаться в теги [CODE=asm] [/CODE] 3. Прежде чем задавать вопрос, см. "FAQ",если там не нашли ответа, воспользуйтесь ПОИСКОМ, возможно, такую задачу уже решали! 4. Не предлагайте свои решения на других языках, кроме Ассемблера. Исключение только с согласия модератора. 5. НЕ используйте форум для личного общения! Все, что не относиться к обсуждению темы - на PM! 6. Проверяйте программы перед тем, как выложить их на форум!!
Доброго времени суток! Мне нужно реализовать программу, которая выводила бы последовательно цифры от 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
Ну, с процедурами - это ты сам как нибудь додумаешь, вот основа программы: получение символа через $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
Ну, с процедурами - это ты сам как нибудь додумаешь, вот основа программы: получение символа через $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, возможно?...