Отвечает: An42
Здравствуйте, Новосельцев Сергей Сергеевич!
Процедура прерывания: (INT)
1. Эта программа которая имеет постоянный адрес (он вычисляется по номеру прерывания)
2. Эта программа всегда заканчивается командой IRET.
3. Получив сигнал на выполнение прерывания, процессор сначала сохраняет в стеке регистр флагов, и полный адрес возврата в прерванную программу (cs:ip), затем он загружает адрес соответствующего прерывания и тем самым переходит на процедуру прерывания.
4. Дойдя до команды IRET процессор из стека извлекает полный адрес возврата (cs:ip) и восстанавливает регистр флагов, программа переходит в ту точку, где она была прервана.
…
init_21h proc far ;Вход в нашу процедуру в stack помещаются (flags,cs,ip)
; cs:ip есть адрес возврата следующей за командой INT 21h в ;какой-либо программе.
;--------------------------------
;Пример: (какая-то другая программа)
; …
; mov ah,0ah
; mov dx,offset mes
; int 21h
;*** cs:ip - Вот в это место мы возвратимся после вызова прерывания
;-------------------------------
cmp ah,9 ; Проверка функции ah=09h
je ok ; если да то на ok
jmp dword ptr cs:[init_21h_proc] ; иначе процессор загружает процедуру по адресу
;cs:[init_21h_proc] и выполняет ее.
;Дойдя до IRET процессор вытолкнет из стека адрес
;возврата (cs:ip) и флаг, программа продолжится в
; нашем примере где три звездочки (*** cs:ip – Вот в это место мы возвратимся после…)
ok: ;Если ah=09h, то
push ds
push dx
push cs
pop ds
mov dx,offset mess ; в dx сохраняется новый адрес сообщения
pushf ; заносим в стек fags
call dword ptr cs:[init_21h_proc] ;заносим в стек cs:ip теперь stack (flags,cs,ip – это
; точка возврата, где следующей командой будет после
; завершение процедуры (pop dx)),
; и переходим на выполнение
; процедуры по адресу cs:[init_21h_proc]
; Дойдя до IRET вытолкнем из стека cs:ip и flags
pop dx ; и продолжим с этой строки.
pop ds
iret ; При выполнение этой команды вытолкнем из стека
; cs:ip и flags и продолжим там, где в нашем примере
; три звездочки (*** cs:ip - Вот в это место мы возврати...)
init_21h_proc dd ?
mess db 'all right !$'
init_21h endp
Удачи
Ответ отправил: An42 (статус: 5-ый класс)
Ответ отправлен: 29.10.2007, 13:32