Получение сегмента данных программы из обработчика прерывания

Тема в разделе "WASM.BEGINNERS", создана пользователем Skycorner, 28 май 2007.

  1. Skycorner

    Skycorner New Member

    Публикаций:
    0
    Регистрация:
    7 май 2007
    Сообщения:
    21
    Подскажите пожалуйста. Есть такая проблема:
    Программа на Паскале инициализирует драйвер мыши, устанавливает в качестве обработчика событий этого драйвера процедуру в своем теле. Таким образом, сама процедура-обработчик практически никак не связана с программой (кроме как значением кодового сегмента и определ. значением смещения в нем). Когда драйвер мыши вызывает процедуру-обработчик, единственное, что он устанавливает, это cs:ip. А каким образом можно получить сегмент данных моей программы внутри этого обработчика? Драйвер мыши при вызове обработчика присваивает DS значение своего сегмента данных.
    Хотел попробовать сохранить значение DS программы где-то по известному адресу (например, в одном из не используемых векторов прерываний - например, для int 0xff), но программа вылетает с ошибкой даже при попытке прочитать слово оттуда (в обработчике). Что это может быть?
    Видел примеры на ассемблере (для обработки мыши), там в начале обработчика стоит команда
    mov ax, data
    mov ds, ax
    Что это за data? Вместо нее подставляется какое-то значение на этапе сборки? Или оно берется из каких-то заголовков, вроде PSP?
    Заранее спасибо за ответ
     
  2. Vov4ick

    Vov4ick Владимир

    Публикаций:
    0
    Регистрация:
    8 окт 2006
    Сообщения:
    581
    Адрес:
    МО
    data подставляет DOS при размещении ЕХЕ-программы в памяти, ссылка на это место программы находится в таблице подстановок в заголовке ехешника, которая вормируется при компоновке.
     
  3. Skycorner

    Skycorner New Member

    Публикаций:
    0
    Регистрация:
    7 май 2007
    Сообщения:
    21
    А каким образом можно прочитать это поле? Только читая EXE-шный файл? В DOSTechHelp сказано, что таблица подстановок находится в exe-шнике (exeheader). Или это я не так понял? И как тогда DOS записывает туда значение сегмента данных, ведь, насколько я знаю, в память exeheader загрузчиком не отображается при старте, формируется только PSP?

    Извините, если вопрос глупый, но можно как-то самому считать значение data, не используя эту "подстановку"?
     
  4. Vov4ick

    Vov4ick Владимир

    Публикаций:
    0
    Регистрация:
    8 окт 2006
    Сообщения:
    581
    Адрес:
    МО
    DOS сама всё делает :derisive: Если в программе написано скажем
    Код (Text):
    1. segment codesg para code ...
    2. ......
    3. mov ax,codesg
    4. ......
    5. ends codesg
    6. ......
    В таблце подстановок будет написано, что надо записать по-такому-то адресу в файле значение CS куда загружена программа и DOS при запуске программы, загрузив её в память, скажем в сегмент 412Bh, подставит его вместо datasg и получится mov ax,412Bh.
     
  5. Skycorner

    Skycorner New Member

    Публикаций:
    0
    Регистрация:
    7 май 2007
    Сообщения:
    21
    Вся проблема в том, что программа не на ассемблере, а на паскале, с ассембл. вставками. Поэтому написать mov ax, data не получается :dntknw:. В вопросе я имел ввиду, как возможно прочитать эту таблицу подстановок "вручную"

    Пытался дизассемблировать IDА'ой текст mov ax, data. Как оказалось, так как IDA восстанавливает сегменты, получил эту же строку: mov ax, dataseg :dntknw:.
     
  6. Ultrin Faern

    Ultrin Faern New Member

    Публикаций:
    0
    Регистрация:
    25 июн 2006
    Сообщения:
    170
    А у паскаля есть функция, возвращающая сегмент данных - DSeg вроде называется.
     
  7. Skycorner

    Skycorner New Member

    Публикаций:
    0
    Регистрация:
    7 май 2007
    Сообщения:
    21
    Там в хелпе сказано, что она возвращает содержимое DS :dntknw:

    Я не понимаю, почему Win98 не позволяет выполнятся такой подпрограмме (это и есть обработчик событий мыши):
    Код (Text):
    1. procedure testmouse; assembler;
    2. asm
    3.   mov ax, 0
    4.   mov es, ax
    5.   mov ax, es:[1020]   {Сдесь программа вылетает}
    6.  
    7.   retf
    8. end;
    Причем если убрать первые 3 строчки подпр., она нормально работает. Win98 пишет GPF, но ведь я обращаюсь в пределах адресов DOS'а, который эмулируется, а не "лажу по чужим сегментам".

    Что интересно, если выполнить то же самое действие из моей программы (а не из процедуры-обработчика), все нормально:
    Код (Text):
    1. mov ax, 0
    2. mov es, ax
    3. mov es:[1020], ds
     
  8. Skycorner

    Skycorner New Member

    Публикаций:
    0
    Регистрация:
    7 май 2007
    Сообщения:
    21
    Vov4ick
    Если нетрудно, расскажите, из каких конкретно областей памяти можно "выдрать" сегмент данных программы, имея только ее сегмент кода

    P.S. нужен еще сегмент стека, но я думаю, его можно получить таким же образом, что и DS
     
  9. Vov4ick

    Vov4ick Владимир

    Публикаций:
    0
    Регистрация:
    8 окт 2006
    Сообщения:
    581
    Адрес:
    МО
    Звиняюсь, я сейчас занят, могу пока только дать ссылку, где почитать
    1. TASM3-1.DOC TASM3-2.DOC
    2. TURBASS1.DOC ...... TURBASS5.DOC
    В этих двух доках подробно написано про TASM и про его взаимодействие с другими языками. Да и вообще полезно иметь такие вещи.
     
  10. Ultrin Faern

    Ultrin Faern New Member

    Публикаций:
    0
    Регистрация:
    25 июн 2006
    Сообщения:
    170
    Укажи, что твоя процедура interrupt, а затем в коде сам ret сделай. Просто компилятор в начало этой процедуры вставит твою заветную строку - mov ds, dataseg