Иллюстрированный самоучитель по Assembler


Организация приложений MS-DOS - часть 19


old_08_offs dw 0 ; Для смещения

old_08_seg dw 0 ;Для сегментного адреса

то к ним можно было бы обращаться без всяких описателей.

Сохранив исходный вектор, можно установить в нем адрес нашего обработчика. Для установки вектора в DOS предусмотрена функция 25h. Она требует указания номера устанавливаемого вектора в регистре AL, a его полного адреса - в парс регистров DS:DX. Здесь нас подстерегает неприятность. Занести в регистр DX смещение нашего обработчика new_08 не составляет труда, это делается командой

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

Однако регистр DS у нас занят - в нем хранится сегментный адрес сегмента данных. Придется на какое-то время сохранить этот адрес, для чего удобнее всего воспользоваться стеком. Откуда взять сегментный адрес обработчика? Между прочим, в языке ассемблера существует специальная конструкция, позволяющая определить сегментный адрес любого поля. В нашем случае она выглядела бы таким образом:

mov AX,seg new_08  ; Получим сегмент с процедурой new_08

mov DS,AX                 ;  Перепишем его в DS

В примере 3-3 использован другой прием - содержимое CS отправляется в стек и тут же извлекается оттуда в регистр DS:

push CS pop DS

После возврата из DOS надо не забыть восстановить исходное содержимое DS, сохраненное в стеке. Инициализация обработчика прерываний закончена. Начиная с этого момента, каждый сигнал таймера будет приводить к прерыванию продолжающейся основной программы и передаче управления на процедуру new_08.

Перед завершением программы необходимо поместить в вектор 8 адрес исходного, системного обработчика, который был сохранен в двухсловном поле old_08. Перед вызовом функции 25h установки вектора в регистры DS:DX надо занести содержимое этого двухсловного поля. Эту операцию можно выполнить одной командой Ids, если указать в качестве ее первого операнда регистр DX, а в качестве второго - адрес двухсловной ячейки, в нашем случае old_08. Именно имея в виду использование этой команды, мы и объявили поле для хранения вектора двухсловным, отчего возникли некоторые трудности при его заполнении командами mov. Если бы мы использовали второй предложенный выше вариант и отвели для хранения вектора две однословные ячейки (old_08_offs и old_08_seg), то команду Ids пришлось бы снабдить описателем изменения размера ячейки:




Начало  Назад  Вперед



Книжный магазин