Вопрос № 105093: Уважаемые эксперты. У меня возникло несколько вопросов по программе Prog10 из 10-ой главы книги Калашникова. Сначала нужно запустить состоящую из двух частей (резидентной и нерезидентной) программу Prog10, потом Test10, и уже после этого запустить в ...Вопрос № 105107: Здраствуйте, у меня возникло несколько вопросов связанных с PSP.
Есть задание, которое состоит в том, что необходимо вывести следующую информацию из PSP:
1. сегментный адрес недоступной памяти,
2. сегментный адрес среды,
3. хвост кома...
Вопрос № 105.093
Уважаемые эксперты. У меня возникло несколько вопросов по программе Prog10 из 10-ой главы книги Калашникова. Сначала нужно запустить состоящую из двух частей (резидентной и нерезидентной) программу Prog10, потом Test10, и уже после этого запустить в отладчике Test10. Суть этого: показать подмену строки из Test10 строкой из Prog10. Когда я в отладчик AFDPRO загружаю Test10, то все сегментные регистры имеют сегмент 26ЕА. После перехвата резидентом Prog10 прерывания 21h из Test10 меняется сегмент CS с 26ЕА на 0DFF.
Потом после команд push CS и pop DS в процедуре Int_21h_proc меняется и сегмент DS и тоже на 0DFF. Вот этого места мне всё понятно. Но вот почему при выполнении команды в этой же процедуре: call dword ptr cs:[ Int_21h_vect] сегмент CS с 0DFF меняется не на 26ЕА, как я этого ожидал, но на какой-то другой, а именно CS=00А7.
Второй вопрос: почему отладчик после выполнения строки call dword ptr cs:[ Int_21h_vect] не показывает изменение регистров BX и ES, ведь в [ Int_21h_vect] находится оригинальный адрес обработчика в BX и ES.
И последний, третий вопрос. В этой же процедуре мы сохраняем регистры DS и DX, которые могут быть изменены. А, собственно говоря, зачем их сохранять, ведь даже если они и изменятся, то команда call dword ptr cs:[ Int_21h_vect] должна, по идее, вызывать адрес оригинального обработчика и тем самым и восстановить эти регистры. Правда, как я уже писал в первом вопросе, отладчик почему-то показывает после call dword ptr cs:[ Int_21h_vect] не регистр 26ЕА, а другой. Значит, я где-то ошибаюсь, но вот где?
Приложение:
Отправлен: 11.10.2007, 19:17
Вопрос задал: Masada (статус: Посетитель)
Всего ответов: 1 Мини-форум вопроса >>> (сообщений: 3)
Отвечает: Зенченко Константин Николаевич
Здравствуйте, Masada!
1) Если Вы запустите программу Test10 без резидента в отладчике, то можно увидеть сегментный адрес оригинального обработчика запоминаем его, запускаем резидент Prog10 и Test10. Смотрим адреса после выполнения строк:
jmp dword ptr cs:[Int_21h_vect]
или
call dword ptr cs:[Int_21h_vect]
Отладчик покажет запомненный рание адрес оригинального обработчика.
Сам отладчик тоже может ставить свои обработчики и т.д. При условии, что загружен только один Ваш резидент, после выполнения перехода команда iret встретися один раз, а при выполнении вызова - два раза. И только после этого сегментный адрес будет установлен на адрес программы Test10.
2)Регистры BX и ES используются функцией DOS ah=35h для возврата результата своей работы и сразу сохраняются в переменную:Int_21h_vect и больше они не нужны. В команде перехода(вызова) используются значения переменной:
dword ptr cs:[Int_21h_vect]; т.е. адрес оригинального обработчика.
3)Команды сохранения регистров DS и DX нужны, т.к. могут использоватся программой Test10 как ей захочится. В этом примере это не видно, но представте в этих регистрах может находится важная для программы информация, к примеру если после вызова функции вывода строки будет стоять команда mov my_data,ax
и значение реристра будет записанно по адресу DS:my_data, т.е. не туда куда планировалось. Обработчик востанавливает только те регистры которые он сохранял сам. Команда iret извлекает из стека 3-и регистра(сегмент кода, указатель следующей команды, востанавливает регистр флагов)
Следим за стеком(для простоты возмем SP=0) программа TEST10:
;sp=0
int 21h
;flag:test10 sp-2
;ip:test10 sp-4
;cs:test10 sp-6 программа Prog10:
. . .
push ds
;ds:prog10 sp-8
push dx
;dx:prog10 sp-10
pushf
;falg:prog10 sp-12
call dword ptr cs:[Int_21h_vect]
;ip:prog10 sp-14
;ip:prog10 sp-16 оригинальный обработчик
. . .
iret;возврат из оргинального обработчика
;cs,ip,flag:prog10 sp-10 программа Prog10:
pop dx
;dx:test10 sp-8
pop ds
;ds:test10 sp-6
iret;возврат из нашего обработчика
;cs,ip,flag:test10 sp=0 программа TEST10:
Удачи!
--------- И только наступив на грабли мы приобретаем драгоценный опыт!
Ответ отправил: Зенченко Константин Николаевич (статус: Специалист)
Ответ отправлен: 11.10.2007, 21:37 Оценка за ответ: 5 Комментарий оценки: Поставил "5", т.к. после уточняющих вопросов мне стало всё ясно.
Вопрос № 105.107
Здраствуйте, у меня возникло несколько вопросов связанных с PSP.
Есть задание, которое состоит в том, что необходимо вывести следующую информацию из PSP:
1. сегментный адрес недоступной памяти,
2. сегментный адрес среды,
3. хвост командной строки,
4. содержимое области среды,
5. путь загружаемого модуля.
Если по пунктам 1) и 2) вопросов нет, то по следующим возникают проблемы - особенно по пунктам 4 и 5 - не совсем понятно, что конкретно имеется в виду? Если кто поможет - буду благодарен.
С уважением МК.
Отвечает: Зенченко Константин Николаевич
Здравствуйте, Козлов Михаил Игоревич!
Смотрите приложение.
Результат работы программы записывается в файл в таком виде:
недоступная память:A000
сегмент окружения:14B0
коммандная строка: control
окружение до пути:PROMPT=$p$g winbootdir=C:WINDOWS COMSPEC=C:WINDOWSCOMMAND.COM xxxxxxxxxxxx TMP=c: emp . . . CMDLINE=q105107 control
путь:C:\_CAT\_LANGASMLIBQ105107.EXE
Запускал с помощью бат-файла в проводнике:
q105107 control
Удачи!
Приложение:
--------- И только наступив на грабли мы приобретаем драгоценный опыт!