Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1] 2  Все   Вниз
  Печать  
Автор Тема: Некоторые вопросы связанные с TSR  (Прочитано 38261 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Skif
Гость
« : 02-07-2005 19:23 » 

1. Что такое MCB (Memory Control Block), как она устроена и где находится?
2. Что такое PSP?
3. Что такое окружение?
4. И вообще если кто знает, как организовать TSR так чтобы при повторном запуске, прога не дублировалась, а наоборот удаляла себя из памяти.

Понимаю, вопросов много, ответы не короткие. Если знаете где про ето толково написано киньте ссылку.
Записан
LP
Помогающий

ru
Offline Offline

« Ответ #1 : 02-07-2005 20:20 » 

Да... ответы не короткие. Насчет ссылок, советую 18-й том библиотеки системного программиста (скачать можно здесь: http://xammep.nm.ru/doc/bsp/index.html). Также думаю, может помочь книга Зубкова.
Цитата
И вообще если кто знает, как организовать TSR так чтобы при повторном запуске, прога не дублировалась, а наоборот удаляла себя из памяти.
У меня как раз курсовая была примерно об этом, полгода назад. TSR выгружалась при повтороном запуске с ключом U. Могу скинуть программу если хочешь. Или начинай писать, а мы будем помогать Улыбаюсь
Записан

Если эта надпись уменьшается, значит ваш монитор уносят
Skif
Гость
« Ответ #2 : 02-07-2005 20:55 » 

Большое спасибо за ссылку, очень интересный материал.
Писать буду сам, если что не получиться или не пойму спрошу.
Чужая программа не поможет, будет соблазн переделать и сдать ее, а препод у нас не дурак, сразу врубиться. так что...
Ждите завтра. к понедельнику надо сделать. Улыбаюсь
Записан
Skif
Гость
« Ответ #3 : 05-07-2005 20:04 » 

Сдачу прог перенесли на "после 20-го".Улыбаюсь Что не может не радовать Улыбаюсь

Появился более конкретный вопрос. Прога которую я должен сделать делает следующее:
1. Она соответственно резидентная. (иначе тема была бы другой) Улыбаюсь Активируется при нажатии клавиш Ctrl+D
2. Получая 2 физических адреса, она котирует дамп памяти в файл.

Соответственно надо написать об-чик 9-го прерывания и т.д. и т.п.
Копирование в файл производится с помощью 21 прерывания.

Вопрос такой: Как избежать возможного повторного запуска 21-го прерывания?
Записан
Alf
Гость
« Ответ #4 : 05-07-2005 20:15 » 

Вопрос такой: Как избежать возможного повторного запуска 21-го прерывания?

Очень просто - не запускать его повторно Ага

Это ведь на самом деле не аппаратное прерывание, а просто типичный способ обращения к сервисам операционной системы (во всяком случае, типичный для 16-разрядных операционных систем). Сколько раз ты его вызовешь, столько раз оно и будет обработано.
Записан
Skif
Гость
« Ответ #5 : 05-07-2005 20:22 » 

Alf
Не в этом продлема. Представь я запустил свою прогу, она стала резидентной перехватив 9 прерывание.
Теперь я о ней забыл. Начал работать с каким-то файлом в DOS-е, допустим писать в него строки с клавы, возможно? Да.
Теперь я случайно нажимаю Ctr+D. Моя прога перехватывает прерывание и начинает писать кусок памяти в файл вызывая 21 прерывание.
Но оно уже вызвано, а повторный вызов 21, насколько я знаю приводит к ошибке (как минимум).
Записан
Skif
Гость
« Ответ #6 : 05-07-2005 20:24 » 

Имеется в виду повторный вызов 21-го, без завершения первого вызова 21-го
Записан
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #7 : 05-07-2005 20:35 » 

Skif, ты пишеш под ДОС? Если да. То в нем нет псевдо паралелизма. Твоей проге всецело принадлежит процессор. Ты вызвал 21h прерывание и пока оно не закончит выполнение, ты не сможеш дальше работать. Нужно только блокировать 9h прерывание от повторного вызова. Так как IRET  прерывания разрешит работу аппаратных прерываний.
Насчет обнаружения копии. Сушествует несколько методов. Одно из них ответ на определное действие. Например ты вызываеш программно прерывание 9h с несушествуюшим кодом вызова, но в твоей проге, этот вызов отрабатывается. Ты уже точно будеш знать, что твоя прога запушена.
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Skif
Гость
« Ответ #8 : 05-07-2005 20:46 » 

Цитата
Ты вызвал 21h прерывание и пока оно не закончит выполнение, ты не сможеш дальше работать. Нужно только блокировать 9h прерывание от повторного вызова. Так как IRET  прерывания разрешит работу аппаратных прерываний.
Не понял! Если я написал новый обработчик для 9h в котором выполняются какие-либо действия с помощью 21h по нажатию клавиш Ctrl+D. И после вызвал допустим 9-ю ф-цию 21h (которая считывает строку) и нажал Ctrl+D у меня мой обработчик не заработает?
Записан
Skif
Гость
« Ответ #9 : 05-07-2005 20:52 » 

Да я пишу под DOS. Про однозадачность знаю.
Цитата
Одно из них ответ на определное действие. Например ты вызываеш программно прерывание 9h с несушествуюшим кодом вызова, но в твоей проге, этот вызов отрабатывается. Ты уже точно будеш знать, что твоя прога запушена.
Про данный метод тоже уже прочитал. Есть еще парочка. (как минимум) Улыбаюсь

И кстати что значит
Цитата
Нужно только блокировать 9h прерывание от повторного вызова.
Зачем? И от какаго повторного вызова?
Записан
Alf
Гость
« Ответ #10 : 05-07-2005 20:54 » 

Я бы не стал блокировать 9-е прерывание. Все-таки программа, которая теряет внешние события, не есть хорошо.

Я бы сделал по-другому. Организовал в программе очередь FIFO. Событие, возникающее по прерыванию 9, быстренько ставит очередной элемент (который хранит границы области памяти для дампа) в эту очередь и завершает обработку. А фоновый процесс (скажем, по таймеру) периодически просматривает очередь и, если она непуста, извлекает из нее очередной элемент и выводит его дамп.

IMHO при таком подходе, во-первых, у тебя никогда не получится вложенности прерываний 21, т.к. очередная запись делается лишь после того, как завершится предыдущая. Во-вторых, не будет проблем, если сделано несколько нажатий подряд, а дамп выводится на медленное устройство вроде флоппи-диска.
Записан
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #11 : 05-07-2005 21:11 » 

Когда идет вход в прерывание обычно ставится команда STI т.е. запрешение аппаратных прерываний. IRET сбрасывает данный флаг. Как я делал. У меня сначала шел вызов оригинальной функции прерывания. Затем я проверял не находится ли мой резидент на выполнении. Если нет, то поднимал флаг активности и делал свои дела. Если да то пропускал просто свою обработку прерывания.
Теперь как бы ты не теряеш прерывание. Но в тоже время твоя прога работает на нем. При этом, если прога будет работать медленнее чем 1/18 секунды. Ты просто потеряеш актуальность дампа.
« Последнее редактирование: 05-07-2005 21:15 от Finch » Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Skif
Гость
« Ответ #12 : 05-07-2005 21:13 » 

Alf проблема не в этом.
Точнее не только в этом
Прога должна сделать только одно копирование и в процессе выполнения может не реагировать на нажатие Ctrl+D
Кстати как это организовать тоже не тревиальный вопрос.Улыбаюсь

Проблема как я уже говорил в другом. Процедура копирования в файл в  любом случае использует 21h
А если мой обработчик был вызван во время выполнения 21h и начал свою работу: получил адреса... начал копировать в файл и вызвал
не завершенное до этого 21h. Возникнет ошибка!!!!!
Записан
Skif
Гость
« Ответ #13 : 05-07-2005 21:20 » 

Цитата
Кстати как это организовать тоже не тревиальный вопрос.
На который и ответил Finch
Цитата
как я делал. У меня сначала шел вызов оригинальной функции прерывания. Затем я проверял не находится ли мой резидент на выполнении. Если нет, то поднимал флаг активности и делал свои дела. Если да то пропускал просто свою обработку прерывания.
Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #14 : 05-07-2005 21:23 » 

Skif, откуда такие сведения об ошибке при вложеном int 21h ?
Видел я резидентные программы, которые активизировались по комбинации клавиш и далее интерактивно работали. Не думаю, что они совсем не использовали int 21h.

По моему, логичнее будет после активизации резидента востановить клавиатурное прерывание и установить перехват после выхода из него, либо блокировать обработку "горячей" комбинации на время интерактивной работы. Зачем вызывать резидент дважды, если можно сделать диалог запроса диапазонов для дампа в цикле - так прерванная программа не успеет изменить память между нажатиями кнопок.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Skif
Гость
« Ответ #15 : 05-07-2005 21:24 » 

И еще, забыл сказать. Адреса вводятся с клавиатуры.
Записан
Alf
Гость
« Ответ #16 : 05-07-2005 21:25 » 

Alf проблема не в этом.
Точнее не только в этом
Прога должна сделать только одно копирование и в процессе выполнения может не реагировать на нажатие Ctrl+D
Кстати как это организовать тоже не тревиальный вопрос.Улыбаюсь

До сих пор нигде не шла речь о необходимости однократного выполнения программы. Если уж есть дополнительные условия задачи, огласи их сразу, мы же не можем все сами угадать.

Организовать однократную реакцию проще простого - после того, как поймал нужную комбинацию клавиш, верни вектор клавиатуры обратно. Гарантированно не будет повторных срабатываний.

Проблема как я уже говорил в другом. Процедура копирования в файл в любом случае использует 21h
А если мой обработчик был вызван во время выполнения 21h и начал свою работу: получил адреса... начал копировать в файл и вызвал
не завершенное до этого 21h. Возникнет ошибка!!!!!

Если аккуратно сохранишь все регистры, которые изменяет твоя TSR, а  потом не забудешь восстановить, то очень сомнительно, что фоновый процесс что-то заметит, даже если в этот момент он тоже обращался к прерыванию 21.
Записан
Skif
Гость
« Ответ #17 : 05-07-2005 21:31 » 

Цитата
Если аккуратно сохранишь все регистры, которые изменяет твоя TSR, а  потом не забудешь восстановить, то очень сомнительно, что фоновый процесс что-то заметит, даже если в этот момент он тоже обращался к прерыванию 21.

Цитата
Skif, откуда такие сведения об ошибке при вложеном int 21h ?
Видел я резидентные программы, которые активизировались по комбинации клавиш и далее интерактивно работали. Не думаю, что они совсем не использовали int 21h.

Народ я бы не гемороился. Препод поставил жеские условия. Уйти от возможности такой ошибки на 100%! Молчу

Цитата
До сих пор нигде не шла речь о необходимости однократного выполнения программы. Если уж есть дополнительные условия задачи, огласи их сразу, мы же не можем все сами угадать.

Организовать однократную реакцию проще простого - после того, как поймал нужную комбинацию клавиш, верни вектор клавиатуры обратно. Гарантированно не будет повторных срабатываний.

Alf заметь я нигде не спрашивал про повторное срабатывание резидента!
А так спасибо, очень полезные замечания, учту.6)
Записан
Skif
Гость
« Ответ #18 : 05-07-2005 21:35 » 

Цитата
если можно сделать диалог запроса диапазонов для дампа в цикле - так прерванная программа не успеет изменить память между нажатиями кнопок.
КАК?Не понял? Если можно по подробнее.
Записан
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #19 : 05-07-2005 21:36 » 

Скиф, я не думаю что ты напоришся на ошибку. Можно конечно и 21 прерывание под себя переписать. т.е. есть вход в прерывание поднять флаг, выход опустить. И в клавиатурном резиденте проверять также и этот флаг. Но я считаю это излишним.
Насчет запрета изменений дампа памяти в Досе, я думаю что не получится. Это Дос. Для любой проги, любой участок ОЗУ доступен. И никто не сможет запретить, что либо писать.
« Последнее редактирование: 05-07-2005 21:40 от Finch » Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Skif
Гость
« Ответ #20 : 05-07-2005 21:36 » 

Сори не знал что 3 ? это Не понял
Записан
Skif
Гость
« Ответ #21 : 05-07-2005 21:39 » 

Цитата
Можно конечно и 21 прерывание под себя переписать. т.е. есть вход в прерывание поднять флаг, выход опустить. И в клавиатурном резиденте проверять также и этот флаг. Но я считаю это излишним.
Как? Где этот флаг ставить, хранить? Как из клавиатурного резидента проверить этот флаг.
В стек его не загонишь, хранить по какому-то конкретному адресу -- бред.
Записан
Skif
Гость
« Ответ #22 : 05-07-2005 21:42 » 

Ладно, спать пора. А то мне чарез 4.20 вставать надо. Завтра прочитаю всё, что напишите.
Заранее спасибо.Улыбаюсь
И подкину еще вопросов если не надоело конечно?
Записан
Alf
Гость
« Ответ #23 : 05-07-2005 21:42 » 

Народ я бы не гемороился. Препод поставил жеские условия. Уйти от возможности такой ошибки на 100%! Молчу

Ну тогда если уж хочешь 100% гарантии, почему бы тебе не забрать на себя заодно и вектор 21? Тогда всегда будешь в курсе, кто вошел в это прерывание, и сможешь подождать его завершения. Главное - не забудь вернуть потом на место при завершении резидента.

Alf заметь я нигде не спрашивал про повторное срабатывание резидента!
А так спасибо, очень полезные замечания, учту.6)

Skif, для резидента это типичный режим - сесть в память, забрать себе нужные прерывания и постоянно их обрабатывать. Для тех, кто имел с ними дело, однократное срабатывание - довольно экзотичный режим работы.
Записан
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #24 : 05-07-2005 21:43 » 

Скиф в своей проге выдели место и храни. У тебя будут два обработчика, которые будут знать точное место. Один обработчк для 9 прерывания и второй для 21 прерывания. Кто тебе запрешает так сделать?
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Skif
Гость
« Ответ #25 : 05-07-2005 21:47 » 

На последок
Цитата
Тогда всегда будешь в курсе, кто вошел в это прерывание
Опять же как?
Цитата
Skif, для резидента это типичный режим - сесть в память, забрать себе нужные прерывания и постоянно их обрабатывать. Для тех, кто имел с ними дело, однократное срабатывание - довольно экзотичный режим работы.
Первый раз пишу резидента, буду знать.
Записан
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #26 : 05-07-2005 21:54 » 

Вот пример резидента из книги Абеля
Код:
;----------------------------------------------------------

ROMAREA SEGMENT AT 400H       ;Область параметров BIOS:
        ORG     17H           ;  адрес флага клавиатуры,
KBFLAG  DB      ?             ;  состояние Alt + Shift
ROMAREA ENDS
;----------------------------------------------------------

CSEG    SEGMENT PARA          ;Сегмент кода
        ASSUME  CS:CS
        ORG     100H
BEGIN:  JMP     INITZ         ;Выполняется только один раз

KBSAVE  DD      ?             ;Для адреса INT 9 BIOS
;               Очистка экрана и установка цветов:
;               ---------------------------------
COLORS  PROC    NEAR          ;Процедура выполняется
        PUSH    AX            ;  при нажатии Alt+Left Shift
        PUSH    BX
        PUSH    CX            ;Сохранить регистры
        PUSH    DX
        PUSH    SI
        PUSH    DI
        PUSH    DS
        PUSH    ES
        PUSHF
        CALL    KBSAV         ;Обработать прерывание
        ASSUME  DS:ROMAREA
        MOV     AX,ROMAREA    ;Установить DS для
        MOV     DS,AX         ;  доступа к состоянию
        MOV     AL,KB  AG     ;  Alt+Left Shift
        CMP     AL,00001010B  ;Alt+Left Shift нажаты?
        JNE     EXIT          ;  нет - выйти
        MOV     AX,0600H      ;Функция прокрутки
        MOV     BH,61H        ;Установить цвет
        MOV     CX,00
        MOV     DX,18 FH
        INT     10H
EXIT:
        POP     ES            ;Восстановить регистры
        POP     DS
        POP     DI
        POP     SI
        POP     DX
        POP     CX
        POP     BX
        POP     AX
        IRET                  ;Вернуться
COLORS  ENDP

;               Подпрограмма инициализации:
;               --------------------------
INITZE  PROC    NEAR            ;Выполнять только один раз



Ассемблер для IBM PC. Программы.                         167


        ASSUME  DS:INTTAB
        PUSH    DS              ;Обеспечить возврат в DOS
        MOV     AX,INTTAB       ;Установить сегмент данных
        MOV     DS,AX
        CLI                     ;Запретить прерывания
                                ;Замена адреса обработчика:
        MOV     AX,WORD PTR KBADDR      ;Сохранить адрес
        MOV     WORD PTR KBSAVE,AX      ;  BIOS
        MOV     AX,WORD PTR BADDR+2
        MOV     WORD PTR KBSAVE+2,AX
        MOV     WORD PTR KBADDR,OFFSET COLORS ;Заменить
        MOV     WORD PTR KBADDR+2,CS          ;  адрес BIOS
        STI                      ;Разрешить прерывания
        MOV     DX,OFFSET INITZE ;Размер программы
        INT     27H              ;Завершить и остаться
INITZE  ENDP                     ;  резидентом

CSEG    ENDS
        END     BEGIN
Кто тебе мешает сделать после KBSAVE и свои переменные. Это для 9 прерывания. Ты можеш и свои прерывания почти по аналогичной схеме сделать.
« Последнее редактирование: 05-07-2005 21:58 от Finch » Записан

Не будите спашяго дракона.
             Джаффар (Коша)
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #27 : 05-07-2005 21:55 » 

Skif, поищи программу techhelp - кладезь информации по PC с MSDOS.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Skif
Гость
« Ответ #28 : 06-07-2005 07:33 » 

Спасибо, я  понял что должен сделать. Какие флаги сделать и кде их хранить ну и т.д. и т.п.

Насчет примера из книги:
1. Попытался скомпилировать:
Turbo Assembler Version 2.0

Assembling file: 1.asm
**Error** 1.asm<9> Illegal use of register
**Error** 1.asm<11> Undefined symbol: INITZ
**Error** 1.asm<26> Undefined symbol: KBSAV
**Error** 1.asm<30> Undefined symbol: KB
**Error** 1.asm<32> Near jump or call to different CS
**Error** 1.asm<36> Extra chracters on line
**Error** 1.asm<56> Illegal instruction
**Error** 1.asm<59> Undefined symbol: INITAB
**Error** 1.asm<61> Undefined symbol: INITAB
**Error** 1.asm<65> Undefined symbol: KBADDR
**Error** 1.asm<66> Can't address with currently ASSUMEd segment registers
**Error** 1.asm<67> Undefined symbol: BADDR
**Error** 1.asm<68> Can't address with currently ASSUMEd segment registers
**Error** 1.asm<69> Undefined symbol: KBADDR
**Error** 1.asm<70> Undefined symbol: KBADDR
error messages:   15
...
Скорее всего просто компилятор не тот, но здесь тоже жесткое ограничение препода.

2. Посмотрел саму прогу, вроде все понятно, кроме:
   - это com? ( ORG     100H)
  - тогда что это?
ROMAREA SEGMENT AT 400H       ;Область параметров BIOS:
        ORG     17H           ;  адрес флага клавиатуры,
KBFLAG  DB      ?             ;  состояние Alt + Shift
ROMAREA ENDS
  - А эта строка меня убила, первый раз такое вижу:   MOV     AL,KB  AG 
Что это за зверь такой KB  AG? Я так понял этой строчкой копируется что-то из состояния клавиатуры в AL?
« Последнее редактирование: 20-12-2007 19:04 от Алексей1153++ » Записан
Alf
Гость
« Ответ #29 : 06-07-2005 08:04 » 

- А эта строка меня убила, первый раз такое вижу: MOV AL,KB AG
Что это за зверь такой KB AG? Я так понял этой строчкой копируется что-то из состояния клавиатуры в AL?

А это случаем не KBFLAG, изуродованный нерадивыми полиграфистами?
Записан
Страниц: [1] 2  Все   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines