Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 13.03.2010, 17:37   #1
Kastaneda
Пользователь
 
Регистрация: 26.02.2010
Сообщений: 22
По умолчанию Организовать аппаратное прерывание DOS

Вопрос заключается в следующем: как организовать аппаратное прерывание? Конкретно нужно вот что: на любом этапе работы программы при нажатии клавиши (например F1 или Esc) вызывать определенную процедуру. То есть например программа занимается выводом строки на экран (ну или не важно чем), нажимаешь клавишу Esc и управление передается на определенный участок кода. Я что-то не могу придумать как это сделать.
Kastaneda вне форума Ответить с цитированием
Старый 13.03.2010, 18:35   #2
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

вешайтесь (перехватывайте на себя) прерывание Int 09 это аппаратное прерывание (IRQ1) вызывается при каждом нажатии и при каждом отпускании клавиши на клавиатуре.
Serge_Bliznykov вне форума Ответить с цитированием
Старый 13.03.2010, 19:19   #3
Kastaneda
Пользователь
 
Регистрация: 26.02.2010
Сообщений: 22
По умолчанию

А как его перехватить? Прочитал описание INT 09, особой ясности не внесло.
Kastaneda вне форума Ответить с цитированием
Старый 14.03.2010, 20:30   #4
kogemrka
Форумчанин
 
Аватар для kogemrka
 
Регистрация: 08.01.2010
Сообщений: 165
По умолчанию

Существует два способа перехватить прерывание:
  1. Напрямую с помощью таблицы векторов прерывания
  2. С помощью функции 35h прерывания 21h и функции 25h прерывания 21h

Если ты хочешь воспользоваться первым способом:
таблица векторов прерываний расположена по адресу 0000:0000h, адрес каждого обработчика занимает 4 байта: 2 байта на сегмент и 2 байта на смещение.
То есть адрес нужного тебе прерывания будет расположен в 0000:0020h (если быть точным, в 0000:0020h - смещение, в 0000:0022h - сегмент).

Тебе нужно просто куда-нибудь сохранить адрес обработчика 9-го прерывания, и вместо него указать адрес своего обработчика.
Кстати, прежде чем будешь записывать что-то в эту таблицу, следует временно отключить прерывания оператором CLI (ну а после записи в таблицу - включить, при помощи STI)

Если захочешь воспользоваться вторым способом:
Функция 35h прерывания 21h позволит получить адрес вектора прерывания (после вызова в es окажется сегмент обработчкиа, а в bx - смещение)
Функция 25h прерывания 21h устанавливает вектор прерывания. В ds нужно положить сегмент нашего обработчика, в dx - смещение.

Ну и в обоих случаях, после своего обработчика следует вызывать стандартный (предварительно записав его адрес). Ну а при выходе из программы следует восстановить старый адрес обработчика.
kogemrka вне форума Ответить с цитированием
Старый 14.03.2010, 20:44   #5
Sparky
Участник клуба
 
Аватар для Sparky
 
Регистрация: 15.05.2009
Сообщений: 1,222
По умолчанию

Вот пример программы, при нажатии ctrl+a выводит hello world
Код:
model tiny
.code
org 100h
main:
;============================================
;яюыучхэшх трсышцы тхътюЁют
        push es
        xor ax,ax
        mov es,ax

;==========================================
;яюыучхэшх тхътюЁр 9 яЁхЁытрэшя
        mov ax,word ptr es:[09h*4]
        mov word ptr old_handler,ax
        mov ax,word ptr es:[09h*4+2]
        mov word ptr old_handler+2,ax

;=========================================
;чрьхэр тхътюЁр
        mov ax,cs
        mov word ptr es:[09h*4+2],ax
        mov ax,offset handler
        mov word ptr es:[09h*4],ax

;=======================================
;юётртшть Ёхчхфхэтэю
        pop es
        mov bx,offset last_byte
        int 27h

;=====================================
;ёюсёттхээыщ юсЁрсютчшъ
handler:
      push es ds si di cx bx dx ax
      xor ax,ax
      mov ah,02h
      int 16h
      test al,00000100b
      jz standart_handler	;если не нажата клавиша ctrl переход на стандартный обработчик
	in al,60h	      
      cmp al,1eh	;если нажата клавиша "a" то выводим на экран hello world в противном случае проверяем "s"
	jne ctrl_s

	mov ax, cs
     mov ds, ax
     mov ax, 0B800h
     mov es, ax
     mov si, offset message
     xor di, di
     mov cx, msg_len
     rep movsb
	
;	push es
;	mov ax,cs
;	mov es,ax
;	
;	mov ah,13h
;	mov cx,11
;	mov dh,3
;	mov dl,3
;	mov bp,offset message
;	int 10h
;	pop es
;	jmp end_handler
ctrl_s:
	cmp al,1fh	;если нажата клавиша "s" то выводим на экран hello world в противном случае переходим на стандартный обработчик
	jne standart_handler
	
;=================================================
;чртхЁшхэшх юсЁрсютъш
end_handler:
        mov al,20h      ;яюёырть ёшуэры "ъюэхц яЁхЁытрэшя"
        out 20h,al  ; ъюэтЁюыыхЁу яЁхЁытрэшщ
        pop ax dx bx cx di si ds es
        iret


;==================================================
;тючтЁрт ётрэфрЁтэюую яЁхЁытрэшя
standart_handler:
        pop ax dx bx cx di si ds es
        jmp dword ptr cs:old_handler
	  iret

        old_handler dd ?
        t db ?
        message db 'H',0Ch,'E',0Ch,'L',0Ch,'L',0Ch,'O',0Ch,' ',0Ch
    		db ' ',0Ch,'W',0Ch,'O',0Ch,'R',0Ch,'L',0Ch,'D',0Ch
        msg_len = $ - message
last_byte:
end main
Единственное, что ограничивает полет мысли программиста-компилятор
Sparky вне форума Ответить с цитированием
Старый 15.03.2010, 08:23   #6
Kastaneda
Пользователь
 
Регистрация: 26.02.2010
Сообщений: 22
По умолчанию

Спасибо, тему можно закрыть.
Kastaneda вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
прерывание в Си Misha_M. Помощь студентам 2 04.02.2010 20:11
Программно-аппаратное взаимодействие iukash Общие вопросы C/C++ 5 02.07.2009 18:01
6 прерывание ленусик Фриланс 1 03.06.2008 16:22
6 прерывание ленусик Помощь студентам 5 30.05.2008 16:57