e2e4 писал(а):
Если речь идет о
Цитата:
Да обработчик нужен в среде DOS. Нерезидентный....я имел ввиду то, что по выходу из программы он должен выгрузится из памяти вернув всё на свои места....
То можно:
1) Написать резидентный обработчик по тому принципу что я описал; После завершения программы его убрать из памяти, вернув старый обработчик в векторах прерываний;
Вообще-то, выгружать резидентный обработчик довольно опасно. После его загрузки мог установиться ещё какой-нибудь обработчик того же прерывания, и тогда корректное удаление нашего обработчика может стать нетривиальным. Безопаснее просто отключить его функции и освободить ставшую ненужной память.
e2e4 писал(а):
2) Обработчик встроить в тело программы, подменить вектор на него, при выходе из программы вернуть вектор на старый обработчик, сам обработчик, как часть программы, убьется стандартным образом очисткой памяти;
Да, верно. Я и сам этим методом пользовался, только давно уже, и сейчас вылетело из головы.
e2e4 писал(а):
По поводу литературы на тему - попробуйте почитать книжки по ассемблеру,
Пример на ассемблере у меня есть.
Код:
.286c
...
CODE SEGMENT PARA PUBLIC 'CODE'
ORG 100H
ASSUME CS:CODE
WV PROC ; scarves.ss
JMP SHORT START
OLD09H LABEL DWORD ; Старый вектор прерывания от клавиатуры.
OFS09H DW ?
SEG09H DW ?
OLD1CH LABEL DWORD ; Старый вектор прерывания от таймера.
OFS1CH DW ?
SEG1CH DW ?
FIN09H DB 0 ; Признак нажатия клавиши.
MS DB 0 ; Признак изменения состояния мыши.
TIMEND DB 0 ; Признак таймерного прерывания.
MMOUSE PROC FAR ; Обработка событий от мыши.
INC MS
RET
MMOUSE ENDP
INT09H: INC FIN09H ; Обработка нажатия клавиши.
JMP OLD09H
INT1CH: INC TIMEND ; Обработка прерывания от таймера.
JMP OLD1CH
ASSUME DS:CODE,SS:CODE
START: MOV BX,1000H
MOV AH,4AH
INT 21H ; Освобождение лишней памяти.
MOV AX,3509H
INT 21H ; Запрос старого вектора прерывания 09H.
MOV SEG09H,ES
MOV OFS09H,BX
MOV AL,1CH
INT 21H ; Запрос старого вектора прерывания 1CH.
MOV SEG1CH,ES
MOV OFS1CH,BX
MOV DX,OFFSET INT1CH
MOV AH,25H
INT 21H ; Установка нового вектора прерывания 1CH.
MOV DX,OFFSET INT09H
MOV AL,09H
INT 21H ; Установка нового вектора прерывания 09H.
MOV AH,0FH
INT 10H ; Запрос текущего видеорежима.
MOV VM,AL
MOV PG,BH
MOV AX,0012H
INT 10H ; Установка графического режима 640x480, 16 цветов.
MOV AX,3533H
INT 21H ; Запрос вектора прерывания 33H.
MOV AX,ES
OR AX,BX
JZ NOMOUS ; Мыши нет.
CMP BYTE PTR ES:[BX],0CEH
JE NOMOUS ; Мыши нет.
XOR AX,AX
INT 33H ; Инициализация мыши.
OR AX,AX
JZ NOMOUS ; Мыши нет.
MOV MP,BL
MOV CX,0000000000011111B
CMP BL,3
JNE TWOB ; Две клавиши.
OR CL,01100000B
TWOB: MOV AX,CS
MOV ES,AX
MOV DX,OFFSET MMOUSE
MOV AX,0014H
INT 33H ; Установка процедуры обработки мыши.
MOV CONDMOU,CX
MOV SEGMOU,ES
MOV OFSMOU,DX
...
MOV AH,00H
MOV AL,VM
INT 10H ; Восстановление видеорежима.
MOV AL,PG
MOV AH,05H
INT 10H ; Восстановление активной видеостраницы.
MOV CX,CONDMOU
LES DX,OLDMOU
MOV AX,000CH
INT 33H ; Восстановление старой процедуры обработки мыши.
...
MOV AX,251CH
LDS DX,OLD1CH
ASSUME DS:NOTHING
INT 21H ; Восстановление старого вектора прерывания 1CH.
MOV AL,09H
LDS DX,OLD09H
INT 21H ; Восстановление старого вектора прерывания 09H.
JMP SHORT TESTB
DELCH: XOR AH,AH
INT 16H ; Чтение символа из буфера клавиатуры.
TESTB: MOV AH,01H
INT 16H ; Проверка наличия символа в буфере клавиатуры.
JNZ DELCH ; Буфер клавиатуры не пуст.
RT: MOV AX,4C00H
INT 21H ; Завершение программы.
WV ENDP
...
; Данные основной программы.
VM DB ? ; Первоначальный видеорежим.
PG DB ? ; Активная видеостраница.
EVEN ; Выравнивание следующего поля на границу слова.
CONDMOU DW ?
OLDMOU LABEL DWORD ; Старый адрес процедуры обработки прерываний от мыши.
OFSMOU DW ?
SEGMOU DW ?
INIDATA EQU THIS WORD
MP DB 0 ; Признак наличия мыши.
...
Только по одному примеру не научишься. Нужно в справочнике почитать описания прерываний.
e2e4 писал(а):
Нескромный вопрос: а зачем в 2006 году использовать ДОС? :)
Недавно наблюдал в банке: на компьютере загружена Windows XP, открыто окно DOS, и в этом окне запущена программа.