На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Перед отправкой сообщения внимательно прочтите правила раздела!!!
1. Запрещается обсуждать написание вирусов, троянов и других вредоносных программ!
2. Помните, что у нас есть FAQ раздела Assembler и Полезные ссылки. Посмотрите, возможно, там уже имеется решение вашего вопроса.

3. Настоятельно рекомендуем обратить особое внимание на правила форума, которые нарушаются чаще всего:
  3.1. Заголовок темы должен кратко отражать её суть. Темы с заголовками типа "Срочно помогите!" или "Ассемблер" будут отправляться в Корзину для мусора.
  3.2. Исходники программ обязательно выделяйте тегами [code]...[/code] (одиночные инструкции можно не выделять).
  3.3. Нежелательно поднимать старые темы (не обновлявшиеся более года) без веской на то причины.

Не забывайте также про главные Правила форума!

Добро пожаловать и приятного вам общения!!! ;)
 
Модераторы: Jin X, Qraizer
  
> СРОЧНО !!! ПРЕРЫВАНИЯ !!!
    Народ !!! Подскажите, как повесить на 9 прерывание
    свой обработчик так, чтобы сначало вызывался старый
    обработчик, а потом исполнялась моя часть обработки
    9-го прерывания ??? Если есть идеи или исходники -
    присылайте на мыло madman@torba.com, не стесняйтесь :)
      так ведь вроде идея любого хука такова, что сначала твой код исполняется, а потом остальной (предназначенный для данного прерывания). А иначе разве может быть ?
        .MODEL Tiny
        .286
        .CODE
        ORG 100h
        Start:
        jmp SetIntVec
        OldInt DD 0
        Handler:
        pushf
        call cs:OldInt
        ;---------------------------------------------;
        ; Твои команды (не забудь сохранять регистры) ;
        ;---------------------------------------------;
        iret
        SetIntVec:
        mov ax,3509h
        int 21h
        mov WORD PTR OldInt[0],bx
        mov WORD PTR OldInt[2],es
        mov ah,25h
        lea dx,Handler
        int 21h
        mov ah,49h ; Советую вот эту штуку делать,
        mov es,ds:[2Ch] ; если не используешь Environment
        int 21h ; (лишнюю память освобождаешь)
        lea dx,SetIntVec
        int 27h
        END Start
          2 7in:
          Пасибо за source :)
          И обьясни, если не лень, че ты делаешь вот тут:
          >mov ah,49h ; Советую вот эту штуку делать,
          >mov es,ds:[2Ch] ; если не используешь Environment
          >int 21h ; (лишнюю память освобождаешь)
          >lea dx,SetIntVec
          >int 27h
          Да, и если у меня TSR-прога, то-есть я итак оставляю в памяти
          только резидентную часть, то нужно ли мне писать у себя
          этот кусок твоего исходника ???
            Когда прога загружается в память, ей выделяется два участка памяти: один под переменные среды (Environment), которые устанавливаются командой DOS SET X=Y , а второй - под программу. Если ты не используешь в _резидентном куске_ этот самый Environment (а я на 99.9\% уверен, что ты его не используешь :) , то его лучше удалить из памяти. Это делается с помощью...
            mov ah,49h
            mov es,ds:[2Ch] ; по адресу [2Ch] находится сегмент с Environment'ом
            int 21h
            Если ты этого не сделаешь, ничего плохого не произойдёт.
            А с помощью...
            lea dx,SetIntVec ; = mov dx,OFFSET SetIntVec
            int 27h
            ...ты оставляешь DX байт программы в памяти (на Environment это никак не влияет). Т.е. DX указывает на следующий байт после последнего нужного тебе :) . Если ты используешь другой метод для оставления проги в памяти (например, int 21h,ah=31h), то последний кусок, естественно, писать не надо.

            Кстати, объясню для чего нужен 'pushf' перед
            'call cs:OldInt'... CALL оставляет в стеке 2 или 4 байта (как в данном случае), а INT - 6 байт (соответственно, IRET вытаскивает из стека 6 байт), первые два из которых - флаги. Т.о. с помощью конструкции 'pushf/call far' мы имитируем INT.
              2 7in:
              Пасибо, понял все что хотел :)
                > Когда прога загружается в память,
                > ей выделяется два участка памяти:
                > один под переменные среды (Environment),
                > которые устанавливаются командой DOS SET X=Y ,
                > а второй - под программу.
                > Если ты не используешь в _резидентном куске_
                > этот самый Environment (а я на 99.9\% уверен,
                > что ты его не используешь :) , то его лучше
                > удалить из памяти. Это делается с помощью...

                Объясните, пожалуйста,
                как конкретно "использовать в _резидентном куске_
                этот самый Enviroment", механизм этого и если
                можно пример.
                  Кстати, свой код прерывания пишут перед родным, потому что после аппаратного прерывания нужно восстановить состояние PIC (обычно достаточно OUT 20H,20H - но не все PC в природе используют 8259-совместимый PIC, например, некоторые японские...)
                    Environment представляет собой несколько ASCIIZ-строк:
                    db 'COMSPEC=C:\COMMAND.COM',0
                    db 'windir=C:\WINDOWS',0
                    и т.д.
                    Затем идёт ещё один ноль, показывающий, что Environment закончился... Потом идёт какое-то слово (не помню, смотреть надо), а затем параметры ASCIIZ. Первый - имя программы, затем первый заданные параметр и т.д. И по-моему заканчивается это всё нулём...
                    Так вот ответ: если ты будешь в проге читать эту область (адрес сегмента находится в PSP:2Ch), в чём я очень сомневаюсь, то удалять её из памяти не надо...
                      2 NOPIK: Оригинальный обработчик это делает сам...
                        А я когда-то очень давно, затирал ещё и часть PSP, т.е. резидентная часть у меня стартавала не от 100h а от 5с или 5d... что-то так, сейчас уж не вспомню.
                        Вот 7in наверное точно знает...
                          Если удалять сегмент окружения, то фрагментация происходить... Не красиво.
                          Поэтому обычно в начале программы берем из окружения все что нучно, а далее затаскиваем себя на место окружения (микрософт клянется, что а) окружение _будет_ б) окружение будет в акурат над сегментом PSP (и MCB егошного)). А перетереть в PSP коммандную строку (начиная с PSP:0080) - это само собой. Резидент должен занимать 256 байт! (меньше не получается (обычно) - PSP должен быть).
                          Че-то еще помню :)
                            2 server_mouse: Если в TechHelp загляну :)
                            2 frostbitten: А если окружения будет не хватать? К тому же это никому не нужный геморрой. И наверняка придётся заголовок енвиронмента (в смысле, "Memory Control Block", как его называют) подправлять.
                            0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                            0 пользователей:


                            Рейтинг@Mail.ru
                            [ Script execution time: 0,0562 ]   [ 15 queries used ]   [ Generated: 28.03.24, 19:22 GMT ]