IPB
ЛогинПароль:

> ПРАВИЛА РАЗДЕЛА!!!

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

> Обработка прерываний
сообщение
Сообщение #1


Знаток
****

Группа: Пользователи
Сообщений: 306
Пол: Мужской
Реальное имя: Евгений

Репутация: -  0  +


Доброго времени суток! Мне нужно реализовать программу, которая выводила бы последовательно цифры от 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

iret
New_1Ch endp

ClnScr proc ;программа очистки экрана
push cx
push ax
push si
xor si,si
mov ah, 7
mov dl,' '
mov cx, 2000

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


Конечно и эти подпрограммы требуют доработок... Вобщем, требуется Ваша помощь... smile.gif
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
 
 Ответить  Открыть новую тему 
Ответов
сообщение
Сообщение #2


Гость






Ну, с процедурами - это ты сам как нибудь додумаешь, вот основа программы: получение символа через $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

s_stack segment stack
db 256 dup(?)
s_stack ends

s_code segment
assume cs: s_code, ds: s_data, ss: s_stack

; подпрограмма обработки прерываний 1Ch
new_1c proc far

; Сохраняем значения всех регистров, которые будут меняться
push ax
push bx
push ds
push es

; DS <- сегмент данных
mov ax, s_data
mov ds, ax

; Проверяем, было ли нажатие
mov ax, 40h ; ES <- BIOS
mov es, ax
mov ax, es:[1Ch] ; AX <- Конец буфера клавиатуры
mov bx, es:[1Ah] ; BX <- Начало буфера клавиатуры
cmp bx, ax ; (BX = AX) => Буфер пуст
jne get_char ; Нет

; Да
jmp go_out

get_char:
mov al, es:[bx] ; Забираем символ из буфера
mov es:[1Ch], bx ; Буфер пуст
mov symbol, al
inc Pressed ; Признак нажатия

go_out:
pop es
pop ds
pop bx
pop ax
iret
new_1c endp

start:
mov ax, s_data
mov ds, ax

; Запомним текущий вектор 1ch
mov ah, 35h
mov al, 1Ch
int 21h

mov old_ip, bx
mov old_cs, es

; Подменим обработчик
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


Сообщение отредактировано: volvo -
 К началу страницы 
+ Ответить 
сообщение
Сообщение #3


Знаток
****

Группа: Пользователи
Сообщений: 306
Пол: Мужской
Реальное имя: Евгений

Репутация: -  0  +


Цитата(volvo @ 15.12.2008 23:02) *
Ну, с процедурами - это ты сам как нибудь додумаешь, вот основа программы: получение символа через $1C, и вывод счетчика на экран:

Большое спасибо за помощь! good.gif
У меня возник ряд вопросов:
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 -
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 

Сообщений в этой теме


 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 





- Текстовая версия 1.05.2024 11:37
500Gb HDD, 6Gb RAM, 2 Cores, 7 EUR в месяц — такие хостинги правда бывают
Связь с администрацией: bu_gen в домене octagram.name