![]() |
|
|
Регистрация Восстановить пароль |
Регистрация | Задать вопрос |
Заплачу за решение |
Новые сообщения |
Сообщения за день |
Расширенный поиск |
Правила |
Всё прочитано |
![]() |
|
|
Опции темы | Поиск в этой теме |
![]() |
#1 |
Пользователь
Регистрация: 12.12.2009
Сообщений: 13
|
![]()
Вопрос возник при анализе программы №10. Учебника Калашникова.
Эта программа - резидент , перехватывающий прерывание 21H. В инициализирующей части - сохранение адреса оригинального обработчика и оставляющая в памяти часть программы, являющейся обработчиком прерывания не оригинальным (пользовательским). Программа корректно работает, но ! я заметил , что ессли в резидентной части программы убрать директиву возврата по адресу оригинального обработчика (или заменить переменную, хранящую адрес возрврата) , то компиляция проходит нормально а при загрузке резидента в память происходит ошибка исполнения. Но этого не должно быть !! до вызова резидентной части на исполнение эта строка вооще не должна выполняться , складываетя дурацкое ощущение, что дос сессия до загрузки резидентной части проверяет ...а собирается ли неоригинальный обработчик вернуть управление оригинальному ...что уж совсем бред какой то. привожу текст программы , прошу пояснить почему эта строка обязательно требуется ... CSEG segment assume cs:CSEG, ds:CSEG, es:CSEG, ss:CSEG org 100h Start: ;Переходим на метку инициализации. Нам нужно будет перехватить прерывание 21h, ;а также оставить программу резидентной в памяти jmp Init ; ==== Обработчик 21h-ого прерывания ==== ;Ниже идет, собственно, обработчик 21h прерывания (он будет резидентный). ;После того, как программа выйдет, процедура Int_21h_proc останется в памяти ;и будет контролировать функцию 09 прерывания 21h. Int_21h_proc proc cmp ah,9 ;Проверим: это функция 09h? je Ok_09 ;Если так, то на метку Ok_09 jmp dword ptr cs:[Int_21h_vect] ; ВОТ ЭТА СТРОКА!!!!!! Ok_09: push ds ;Сохраним регистры push dx push cs ;Адрес строки должен быть в DS:DX pop ds ;Выводим нашу строку (My_string) вместо той, которую должна вывести ;программа, вызвавшая 21h-ое прерывание mov dx,offset My_string pushf ;Так надо! Позже рассмотрим call dword ptr cs:[Int_21h_vect] pop dx ;Восстановим использованные регистры pop ds iret ;Продолжим работу (выйдем из прерывания) ;Программа, выводящая строку, считает, что на экран было выведено ее ;сообщение. Но на самом деле это не так! ;Переменная для хранения оригинального адреса обработчика 21h Int_21h_vect dd ? ;Строка, которая будет выводится My_string db 'Моя строка!$' int_21h_proc endp ; ==== Конец обработчика 21h-ого прерывания ==== ;Со следующей метки нашей программы уже не будет в памяти ;(это нерезидентная часть). Она затрется сразу после выхода (после ;вызова прерывания 27h). Init: ;Установим наш обработчик (Int_21h_proc) (адрес нашего обработчика, ;если быть точнее) на 21h прерывание. Это позволяет сделать функция ;25h прерывания 21h. ;Но прежде нам нужно запомнить оригинальный адрес этого прерывания. ;Для этого используется функция 35h прерывания 21h: mov ah,35h ;AH содержит номер функции (это понятно) mov al,21h ;AL указывает номер прерывания, адрес (или вектор) ;которого нужно получить int 21h ;Теперь в ES:BX адрес (вектор) 21h прерывания ;(ES - сегмент, BX - смещение) mov word ptr Int_21h_vect,bx mov word ptr Int_21h_vect+2,es ;! Обратите внимание на форму записи ;Итак, адрес сохранили. Теперь перехватываем прерывание: mov ax,2521h mov dx,offset Int_21h_proc ;DX должен указывать на наш ;обработчик (т.е. Int_21h_proc) int 21h ;Все! Теперь, если какая-либо программа вызовет 21h, то вначале компьютер ;попадет на наш обработчик (Int_21h_proc). ;Что осталось? Завершить программу, оставив ее резидентной в памяти ;(чтобы никто не затер наш обработчик, иначе компьютер зависнет). mov dx,offset Init int 27h ;Прерывание 27h выходит в DOS (как 20h), при этом оставив нашу программу ;резидентной. DX должен указывать на последний байт, остающийся в памяти ;(это как раз метка Init). Т.е. в памяти остается от 0000h до адреса, ;по которому находится метка Init. CSEG ends end Start Последний раз редактировалось Les_55; 13.12.2009 в 14:11. |
![]() |
![]() |
![]() |
#2 |
Пользователь
Регистрация: 13.12.2009
Сообщений: 23
|
![]()
Имейте совесть
![]() Вы же перезаписываете весь вектор 21h! А вдруг кто-нибудь дёргает какую-то из функций 21h в этот момент? Что будет? Может и не дёрнуть, тогда ваш резидент, несомненно, загрузится и будет ждать своего часа, чтобы свалиться ![]() |
![]() |
![]() |
![]() |
#3 |
Пользователь
Регистрация: 12.12.2009
Сообщений: 13
|
![]()
Это не так. Программа перехватывает только 09-ю функцию прерывания (вывод строки на экран). Остальные направляет в оригинальный обрабочтик...так вот требование системы на наличие такого возвращения меня и смущает...я не могу допустить что система может анализировать код на "потенциальную зависаемость"...да, если убрать эту строку код по факту зависнет ...но система знать заранее этого просто не может !!! (может резидент перед загрузкой все же как то "тестируется" а ??? :-O )
|
![]() |
![]() |
![]() |
#4 | |
equ asm
Участник клуба
Регистрация: 02.05.2009
Сообщений: 1,605
|
![]() Цитата:
|
|
![]() |
![]() |
![]() |
#5 |
Пользователь
Регистрация: 12.12.2009
Сообщений: 13
|
![]()
Да я согласен с Вами все функции перехватывает. Однако это не объясняет мне почему операционная система зависает , если я уберу эту строку. Зависает не при вызове резидета , а при загрузке его в память.
|
![]() |
![]() |
![]() |
#6 |
Пользователь
Регистрация: 13.12.2009
Сообщений: 23
|
![]()
Значит при загрузке его в память вызывается не-девятая функция и всё падает ))
У меня (winxp sp3) ничего не вызывается, резидент ждёт некоторое время прежде чем упасть )) |
![]() |
![]() |
![]() |
#7 |
Форумчанин
Регистрация: 02.04.2008
Сообщений: 358
|
![]()
скомпиллил прогу из поста 1, все работает
неплохо пишу на ассемблере для 80х86
icq: 3(один)7748666 mail: airyashov(а)inbox.ru |
![]() |
![]() |
![]() |
#8 |
Пользователь
Регистрация: 12.12.2009
Сообщений: 13
|
![]() |
![]() |
![]() |
![]() |
#9 |
equ asm
Участник клуба
Регистрация: 02.05.2009
Сообщений: 1,605
|
![]()
А вроде никто и не говорил, что она не работает. Просто пытаемся объяснить, что 21-е прерывание вызывается гораздо чаще, чем думает ТС.
|
![]() |
![]() |
![]() |
#10 | |
Пользователь
Регистрация: 12.12.2009
Сообщений: 13
|
![]() Цитата:
![]() У вас в winxp sp3 ...вы запускаете сессию эмуляции дос и в ней программма загружается без красной строки ? |
|
![]() |
![]() |
![]() |
|
Опции темы | Поиск в этой теме |
![]() |
||||
Тема | Автор | Раздел | Ответов | Последнее сообщение |
Из Dos под Win | Nozema | Фриланс | 3 | 30.10.2009 17:34 |
borland C++под DOS | Xeon332 | Помощь студентам | 9 | 20.09.2008 20:50 |
консоль на ASM под Win | ёжик | Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM | 15 | 24.11.2007 12:20 |
Оформление под Win Vista | Yar | Помощь студентам | 1 | 28.10.2007 08:38 |
Эмулятор Win под Linux | Asain-Asa | Linux (Ubuntu, Debian, Red Hat, CentOS, Mint) | 1 | 10.11.2006 07:21 |