Файл: О.А.Калашников. Ассемблер Это Просто. Учимся программировать.pdf

ВУЗ: Не указан

Категория: Книга

Дисциплина: Программирование

Добавлен: 16.02.2019

Просмотров: 36874

Скачиваний: 1802

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
background image

Глава 15. Обработка аппаратных прерываний 

159 

абсолютно  не  надо!  Поэтому  мы  вызываем  прежний  обработчик  прерывания 

21h

который использовался до загрузки нашего резидента. Это может быть как другой 
резидент, так и само ядро DOS. Получается своего рода "фильтр" прерывания 

21h

Программист  может  "фильтровать"  те  или  иные  функции  прерывания  и  делать  
с ними все, что посчитает нужным! 

Итак, передали управление прежнему обработчику. Он нам вернул информацию 

о найденном файле в DTA. Что дальше? 

"Но мы не знаем, где в памяти находится этот DTA!" — скажете вы. Верно, не 

знаем.  Он  может  быть  где  угодно.  Получить  адрес  DTA  позволяет  функция 

2Fh

прерывания 

21h

. Но обратите внимание, как мы теперь вызываем 

21h

int 21h 

Почему так? Вызвав 

21h

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

int 21h

, процессор попадет на 

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

Int_21h_proc

. Рассуждаем 

так:  в  этот  момент  в  регистре 

ah

  у  нас  находится  число 

2Fh

.  Теперь  посмотрите 

внимательно,  что  произойдет,  если  наша  процедура 

Int_21h_proc

  получит  управ-

ление с находящимся в 

ah

 числом 

2Fh

А если она же получит управление с числом 

4Fh

 в 

ah

? Вот именно! Поэтому мы, 

в случае вызова прерывания 

21h

 с числом 

4Eh

 или 

4Fh

, вызываем напрямую преж-

ний обработчик командой 

call dword ptr cs:[Int_21h_vect]

, а с любым другим 

числом —  наш  обработчик  командой 

int  21h

.  Зачем так делать? Дело в том, что 

второй вариант занимает меньше байтов, да и работает быстрее... 

Адрес DTA получили. Теперь необходимо получить случайное число. Это мож-

но сделать, вызвав функцию 

2Ch

  прерывания 

21h

, которая вернет в определенных 

регистрах текущее время. В файле-приложении вы найдете подробное описание.  

1

5.5. Логические команды процессора 

Пришло время рассмотреть логические команды процессора, которые использу-

ются в файле-приложении. Логических команд всего несколько: 

and

or

xor

Проще  всего  объяснить  их  действие  на  примерах.  Главное —  понять  принцип. 

Мы  еще  не  раз  будем  использовать  логические  операторы.  Это  одна  из  быстрых  
и простых вещей ассемблера, в отличие от языков высокого уровня. 

15.5.1. Оператор or  

Оператор 

or

  (ИЛИ)  служит  для  включения  определенных  битов  (не  байтов!)  

в регистре, переменной или в памяти (табл. 15.1 и рис. 15.2). 

mov    ax,1010b 

or     ax,1111b 

;Теперь ax=1111b=0Fh. Таким образом мы включили (установили) 

;первые четыре бита. 


background image

Часть III. Файловая оболочка, вирус, резидент 

160 

Таблица 15.1. Результат работы команды 

or

Первый бит 

Второй бит 

Результат работы or 

Рис. 15.2. Результат выполнения команды or 

mov    ah,1000b 
or     ah,1001b 
;Теперь ah=1001b. Таким образом мы установили нулевой бит, а третий был 
;уже установлен до нас, но он остался неизмененным!  

15.5.2. Оператор and 

Оператор 

and

 (И) служит для исключения битов (табл. 15.2, рис. 15.3). 

mov    ax,1010b 
and    ax,0101b 
;Теперь ax=0000b=0h. Таким образом мы исключили первый и третий биты 
;(отсчет справа налево, начиная с нуля). 

Таблица 15.2. Результат работы команды 

and

Первый бит 

Второй бит 

Результат and 


background image

Глава 15. Обработка аппаратных прерываний 

161 

Рис. 15.3. Результат выполнения команды and 

mov    ah,1001b 
and    ah,0001b 
;Теперь ah=0001b. Таким образом мы исключили третий бит.  

15.5.3. Оператор xor 

Оператор 

xor

    (исключающее  ИЛИ)  используется  в  основном  для кодирования 

данных (табл. 15.3, рис. 15.4). 

mov    ah,1010b 
xor    ah,1100b        ;Теперь ah=0110b=06h 

Таблица 15.3. Результат работы команды 

xor

Первый бит 

Второй бит 

Результат xor 

Рис. 15.4. Результат выполнения команды xor 


background image

Часть III. Файловая оболочка, вирус, резидент 

162 

Оператор 

xor

 очень удобен также для включения/исключения одного бита: 

mov al,0    ;al=0 
xor al,1    ;al=1 
xor al,1    ;al=0 
xor al,1    ;al=1 и т. д. 

Именно  этим  оператором  мы  быстро  и  красиво  аннулировали  регистры  в  пре-

дыдущих главах.  

15.6. Аппаратные прерывания  
нашего резидента 

Кроме аппаратных прерываний, в процедуре обработки прерывания 

21h

 мы пока 

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

15.6.1. Аппаратное прерывание 05h 

Прерывание 

05h

 активизируется (т. е. процессор передает управление процедуре 

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

05h

)  при  нажатии  комбинации  клавиш  <Shift>+<Print 

Screen>. В этот момент содержимое текстового экрана выводится на принтер (что 
изначально  и  делает  оригинальный  обработчик  BIOS).  Теперь  вы  знаете,  какое 
прерывание  направляет  содержимое  экрана  на  принтер.  Ничего  не  мешает  про-
граммисту установить свой обработчик на прерывание 

05h

. Мы это и делаем в на-

шем резиденте (процедура 

Int_05h_proc

). 

После загрузки резидента в память пользователь нажимает комбинацию клавиш 

<Shift>+<Print Screen> и... содержимое экрана выводится не на принтер, а сохраня-
ется в текстовый файл в текущем каталоге. Имя файла — Screen.txt. Это работает 
наша  процедура!  Абсолютно  ничего  сложного  в  ней  нет.  Далее  мы  рассмотрим  
в двух словах принцип работы нашего обработчика прерывания 

05h

. Дополнитель-

ную информацию вы найдете в файле-приложении. 

Как вы уже знаете, один символ на экране занимает 2 байта: символ и его атри-

бут.  Атрибуты-то  нам  не  надо  сохранять  в  текстовом  файле!  Поэтому  их  нужно 
"отсеять", оставив только символы. Для временного хранения символов мы исполь-
зуем  память  первой  видеостраницы.  Затем,  вызвав  функцию 

40h

  прерывания 

21h

мы сохраняем отделенные от атрибутов символы в текстовый файл Screen.txt. Все! 
Можно смотреть этот файл в любом текстовом редакторе... 

15.6.2. Аппаратное прерывание 09h 

Как уже упоминалось, это прерывание вызывается в случае, если пользователь 

нажал или отпустил какую-нибудь клавишу. В компьютере существуют порты вво-
да/вывода, которые сейчас мы подробно рассматривать не будем. При нажатии или 
отпускании  клавиши  в  порт 

60h

  заносится  ее  скан-код.  Чтобы  получить  из  порта 

число, нужно пользоваться оператором 

in


background image

Глава 15. Обработка аппаратных прерываний 

163 

Следует отличать ASCII-код от скан-кода. Одна из функций прерывания 

09h

 — 

преобразование скан-кода в ASCII-код. Для чего это нужно — рассмотрим позже. 
Сейчас главное — уловить принцип работы разных прерываний (листинг 15.9). 

Листинг 15.9. Обработчик прерывания 09h 

... 
(1) Int_09h_proc proc 
(2)    pusha 
(3)    in al,60h 
(4)    cmp al,58h 
(5)    jne No_F12 
 
(6)    xor cs:Num_status,1 
(7) No_F12: 
(8)    popa 
(9)    jmp dword ptr cs:[Int_09h_vect] 
 
(10) Int_09h_vect dd ? 
(11) Int_09h_proc endp 
... 

Скан-код  клавиши  <F12> — 

58h

  (полный  список  скан-кодов  клавиш  см. в  при-

ложении 3).  Мы  вначале  получаем  из  порта 

60h

  скан-код  нажатой  клавиши.  Если 

это <F12>, то инвертируем нулевой бит некой переменной 

Num_status

 и передаем 

управление  оригинальному  обработчику 

09h

.  Если  мы  не  передадим  управление 

оригинальному  обработчику,  то  пользователь  не  сможет  работать  с  клавиатурой, 
т. к.  прерывание 

09h

  заносит  в  буфер  клавиатуры  ASCII-код  нажатой  клавиши.  

Но мы-то этого в нашем обработчике не делаем! Можно, конечно, самому написать 
подобную процедуру, но мы не ставили задачу сделать это в данной главе. 

Что же касается "таинственной" переменной 

Num_status

, мы рассмотрим ее чуть 

позже... 

15.6.3. Аппаратное прерывание 1Ch 

Это прерывание примечательно тем, что оно само по себе вызывается примерно 

18,2 раза в секунду. Если мы напишем какую-нибудь процедуру и установим на нее 
вектор прерывания 

1Ch

, то она будет автоматически вызываться указанное количе-

ство раз. 

В нашем случае процедура 

Int_1Ch_proc

 "просматривает" содержимое нулевой 

страницы и заменяет символы "A" и "a" на "O" и "o". Причем все это происходит  
с периодичностью 18,2 раза в секунду. Начало данной процедуры такое: 

... 
cmp cs:Num_status,0