Вопрос № 20919: У меня такой вопрос.... Как можно отработать в процедуре прерывание без int, a потом вернуться обратно в процедуру.... Вот моя процедура...
Smena_Stranici proc
mov ax,0500h
pushf
call dword ptr cs:[Label2]
...
Вопрос № 20919
У меня такой вопрос.... Как можно отработать в процедуре прерывание без int, a потом вернуться обратно в процедуру.... Вот моя процедура...
Smena_Stranici proc
mov ax,0500h
pushf
call dword ptr cs:[Label2]
jmp dword ptr cs:[Int_10h_vect] ;передаем управление
;оригинальному обработчику 10h
Label2:
ret
Smena_Stranici endp
Отправлен: 15.05.2005, 23:51
Вопрос задал: edson (статус: Посетитель)
Всего ответов отправлено: 2
Отвечает: DSota
Здравствуйте, edson! Вместо "call dword ptr cs:[Label2]" - вызов по адресу процедуры напиши просто call Label2
--------------- комментарий Ayl. Не пройдет так, а приведет к плохим вещам.
Объясняю. Перед выполнением инструкции call Label2 в стеке находятся флаги. После выполнения команд call Label2 и ret стек не изменяется! Далее выполняется переход на обработчик по jmp, в результате работы которого в конце будет выполнен iret. Команда iret ожидает обнаружить в
стеке дальний адрес возврата и сохраненные флаги. Она вытащит из стека верхнее слово (а это флаги) и поместит его в регистр IP. В регистр CS будет записано то слово, которое находится в стеке под флагами, в регистр флагов - следующее. И управление будет передано по адресу CS:IP, то есть непонятно куда. Результат - зависание в лучшем случае.
Вообще все делается 2-мя командами: pushf call dword ptr cs:[Int_10h_vect]
Ответ отправил: DSota (статус: Студент)
Отправлен: 16.05.2005, 08:38 Оценка за ответ: 4 Комментарий оценки: Ошибка - "Программа выполнила недопустимую инструкцию".
Отвечает: Ayl
Здравствуйте, edson!
Объясни, пожалуйста, чего ты хочешь добиться этим кодом:
pushf
call dword ptr cs:[Label2]
Label2:
ret
?
Во-первых, call dword ptr вытащит 4 байта с адреса, начинающегося по метке Label2. Т.е. C9 и еще 3 байта. Затем он использует их в качестве дальнего адреса для передачи управления. Т.е. передаст управление неизвестно куда.
Во-вторых, даже если ты напишишь так:
call Label2
то при возврате по ret из стека будет удалена точка возврата.
А вообще, чтобы вызвать старый обработчик прерывания и затем вернуться обратно, используй связку:
pushf
call dword ptr cs:[Int_10h_vect]
В чем проблема-то? Ты же ровно это делаешь в других обработчиках. Почему же здесь у тебя проблемы и ты начинаешь извращаться?
jmp cs:<адрес старого обработчика> переходит на обработчик и по iret возвращается в прерванную программу (стек не изменяется по jmp).
pushf
call cs:<адрес старого обработчика> переходит на обработчик и по iret возвращается обратно на следующую инструкцию. Потому что ты сам в стек помещаешь флаги, а дальний адрес возврата помещается по команде call far.
Ответ отправил: Ayl (статус: Профессор)
Отправлен: 16.05.2005, 13:38 Оценка за ответ: 5 Комментарий оценки: Спасибо!!! Я просто с call и jmp немного запутался...... Но уже всё в порядке...