Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 13.12.2009, 13:42   #1
Les_55
Пользователь
 
Регистрация: 12.12.2009
Сообщений: 13
По умолчанию Не понимаю логику DOS. (резидент под win-16)

Вопрос возник при анализе программы №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.
Les_55 вне форума Ответить с цитированием
Старый 13.12.2009, 18:03   #2
Nowar
Пользователь
 
Регистрация: 13.12.2009
Сообщений: 23
По умолчанию

Имейте совесть
Вы же перезаписываете весь вектор 21h!
А вдруг кто-нибудь дёргает какую-то из функций 21h в этот момент? Что будет? Может и не дёрнуть, тогда ваш резидент, несомненно, загрузится и будет ждать своего часа, чтобы свалиться
Nowar вне форума Ответить с цитированием
Старый 13.12.2009, 21:12   #3
Les_55
Пользователь
 
Регистрация: 12.12.2009
Сообщений: 13
По умолчанию

Цитата:
Сообщение от Nowar Посмотреть сообщение
Имейте совесть
А вдруг кто-нибудь дёргает какую-то из функций 21h в этот момент?
Это не так. Программа перехватывает только 09-ю функцию прерывания (вывод строки на экран). Остальные направляет в оригинальный обрабочтик...так вот требование системы на наличие такого возвращения меня и смущает...я не могу допустить что система может анализировать код на "потенциальную зависаемость"...да, если убрать эту строку код по факту зависнет ...но система знать заранее этого просто не может !!! (может резидент перед загрузкой все же как то "тестируется" а ??? :-O )
Les_55 вне форума Ответить с цитированием
Старый 13.12.2009, 22:13   #4
Goodwin98
equ asm
Участник клуба
 
Аватар для Goodwin98
 
Регистрация: 02.05.2009
Сообщений: 1,605
По умолчанию

Цитата:
Это не так. Программа перехватывает только 09-ю функцию прерывания
Код перехватывает всё прерывание int 21h. А после того, как вы уберете проверку на то, что вызвалось именно 09, будут обрабатываться вообще все его ф-ции.
Какой вопрос - такой ответ. Не забываем пользоваться поиском, гуглом.
Помощь в выполнении работ по ассемблеру ICQ:2725322O4
Goodwin98 вне форума Ответить с цитированием
Старый 14.12.2009, 00:42   #5
Les_55
Пользователь
 
Регистрация: 12.12.2009
Сообщений: 13
По умолчанию

Цитата:
Сообщение от Goodwin98 Посмотреть сообщение
Код перехватывает всё прерывание int 21h. А после того, как вы уберете проверку на то, что вызвалось именно 09, будут обрабатываться вообще все его ф-ции.
Да я согласен с Вами все функции перехватывает. Однако это не объясняет мне почему операционная система зависает , если я уберу эту строку. Зависает не при вызове резидета , а при загрузке его в память.
Les_55 вне форума Ответить с цитированием
Старый 14.12.2009, 01:36   #6
Nowar
Пользователь
 
Регистрация: 13.12.2009
Сообщений: 23
По умолчанию

Значит при загрузке его в память вызывается не-девятая функция и всё падает ))
У меня (winxp sp3) ничего не вызывается, резидент ждёт некоторое время прежде чем упасть ))
Nowar вне форума Ответить с цитированием
Старый 14.12.2009, 07:56   #7
airyashov
Форумчанин
 
Регистрация: 02.04.2008
Сообщений: 358
По умолчанию

скомпиллил прогу из поста 1, все работает
неплохо пишу на ассемблере для 80х86
icq: 3(один)7748666
mail: airyashov(а)inbox.ru
airyashov вне форума Ответить с цитированием
Старый 14.12.2009, 08:15   #8
Les_55
Пользователь
 
Регистрация: 12.12.2009
Сообщений: 13
По умолчанию

Цитата:
Сообщение от airyashov Посмотреть сообщение
скомпиллил прогу из поста 1, все работает
Это правда, прога работает. но если убрать выделенную строку, то компилируется и не работает, однако я не могу понять почему. Об этом и был мой вопрос
Les_55 вне форума Ответить с цитированием
Старый 14.12.2009, 08:16   #9
Goodwin98
equ asm
Участник клуба
 
Аватар для Goodwin98
 
Регистрация: 02.05.2009
Сообщений: 1,605
По умолчанию

А вроде никто и не говорил, что она не работает. Просто пытаемся объяснить, что 21-е прерывание вызывается гораздо чаще, чем думает ТС.
Какой вопрос - такой ответ. Не забываем пользоваться поиском, гуглом.
Помощь в выполнении работ по ассемблеру ICQ:2725322O4
Goodwin98 вне форума Ответить с цитированием
Старый 14.12.2009, 08:20   #10
Les_55
Пользователь
 
Регистрация: 12.12.2009
Сообщений: 13
По умолчанию

Цитата:
Сообщение от Nowar Посмотреть сообщение
Значит при загрузке его в память вызывается не-девятая функция и всё падает ))
У меня (winxp sp3) ничего не вызывается, резидент ждёт некоторое время прежде чем упасть ))
Версия правдоподобная. Но выходит , что при загрузе резилента в память операционная система что то там делает с прерываниями и 21H ,а у меня не справшивает , что есть западло....
У вас в winxp sp3 ...вы запускаете сессию эмуляции дос и в ней программма загружается без красной строки ?
Les_55 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Из 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