1. Этот сайт использует файлы cookie. Продолжая пользоваться данным сайтом, Вы соглашаетесь на использование нами Ваших файлов cookie. Узнать больше.

Обработчик прерывания мыши на асме в Bp7

Тема в разделе "Софт", создана пользователем Пончик, 05.10.02.

  1. Пончик

    Пончик Гость

    procedure setintvektor(s:word);
    begin
    asm
    mov ax,s
    int 33h
    mov ax,000ch
    mov cx,0002h
    mov dx,offset @work
    int 33h
    mov ah,0
    int 16h
    mov ax,000ch
    mov cx,0000h
    int 33h
    @work:
    {ххххх


    ххх }
    retf
    end
    end;

    Никак не могу пронять почему данныи обработчик
    подвешивает тачку под досом
    и заставляет виндут закрывать BP7?Может есть тот чел которыи разбереться?
     
  2. Nevermind

    Nevermind Активный участник

    2.027
    0
    ХЗ.
    Для начала баг: Данная ф-я (INT 33h/000Ch) требует на входе наличие адреса обработчика в ES: DX. Должна происходить запись CS в ES, чего у тебя нет. Правда, устранение этой ошибки ни к чему не приводит.
    Исходя из того, что
    а) Установка хэндлера происходит правильно (учитывая исправление)
    б) Обработчик не получает управление вообще (ошибка возникает раньше)
    можно заключить, что ошибка - на уровне системы.
    Поправка к б): Следующий кусок (использовались несколько модифицированные функции модуля F_MOUSE) тоже выдает ошибку, но затем выполняет то, что указано в обработчике (правда, затем прога падает, но все же):

    USES DOS, CRT;

    const
    OldUserProc: Pointer=NIL;
    var
    UserProc: Pointer absolute OldUserProc;
    OldAX: Word;
    REG: Registers;

    Procedure MouseHandler; Far; Assembler;
    {Ассемблерный интерфейс для вызова обработчика}
    ASM
    {Сохраняем в стеке регистры}
    push bp
    push ds
    push es
    push ax
    mov ax,SEG @DATA
    mov ds,ax
    pop ax
    mov OldAX,ax
    {Проверяем условия вызова}
    mov ax,Word ptr [OldUserProc] {ax = сегментадрес}
    or ax,Word ptr [OldUserProc+2] {Адрес = NIL?}
    jz @ {Да - не вызывать}
    {Готовим вызов процедуры пользователя}
    mov ax,OldAX
    push ax {Mask := ax}
    push bx {Buttons:=bx}
    push cx {X:=cx}
    push dx {Y:=dx}
    push di {DX:=di}
    push si {DY:=si}
    {Вызываем процедуру пользователя}
    call [UserProc]
    {Выход из процедуры: восстанавливаем регистры}
    @: pop es
    pop ds
    pop bp
    ret far
    end; {MouseHandler}
    {----------------------}
    Procedure SetMouseHandler(Mask:Word; Proc:Pointer);
    {Устанавливает адрес и условия вызова обработчика}
    begin
    {if IsMouse then} with Reg do
    begin
    UserProc:=Proc;
    ax:=$0C;
    cx:=Mask;
    es:=seg(MouseHandler);
    dx:=ofs(MouseHandler);
    Intr($33,Reg)
    end
    end; {SetMouseHandler}
    {----------------------}

    Procedure Simple (Mask, Buttons,X,Y,DX,DY:Integer);
    Begin
    Write('Message');
    End;

    BEGIN
    SetMouseHandler(2, @Simple);
    repeat until keypressed;
    END.

    В качестве замены можно использовать следующее:
    Куда-нибудь сохраняем адрес хэндлера события, статус мышки и фильтр для вызова хэндлера. Затем падаем на INT 8. В качестве обработчика можно использовать примерно следующее:

    PUSHF
    CALL DWORD PTR CS:[saved_i8_handler]
    MOV AX, 03h
    INT 33h

    **обработка полученных данных + коррекция на фильтр**

    TEST [регистр с результирующей информацией], [он же]
    JZ SkipExecution

    CALL **обработчик сообщения**

    SkipExecution:
    IRET

    А вот то, что не понятно уже мне:
    XOR AX, AX
    MOV ES, AX
    MOV AX, ES:[33h*4] ; AX=0001h
    MOV BX, ES:[33h*4+2] ; BX=0D80h

    Значит, адрес обработчика инта 33h находится в 0D8h:0001h. Смотрим туда:
    *************************
    0D80:0001 6390CA08 arpl [bx+si+08CA],dx
    0D80:0005 00433A add [bp+di+3A],al
    0D80:0008 5C pop sp
    0D80:0009 57 push di
    0D80:000A 49 dec cx
    0D80:000B 4E dec si
    0D80:000C 44 inc sp
    0D80:000D 4F dec di
    0D80:000E 57 push di
    0D80:000F 53 push bx
    0D80:0010 FF db FF
    0D80:0011 FF db FF
    0D80:0012 FF db FF
    *************************
    Что-то не тянет это на обработчик. В чем дело?
     
  3. Пончик

    Пончик Гость

    Дык я не понял кагданадо регистры захранять перед обработчиком или перед его установкои?
     
  4. Nevermind

    Nevermind Активный участник

    2.027
    0
    Перед установкой - нет.
    Перед обработчиком - тоже нет.
    Приведу кусок хелпа:
    Info: This installs a custom mouse event handler. Specify which events
    you want to monitor via bit-codes in CX, and pass the address of
    your handler in ES: DX. When any of the specified events occur,
    the code at ES: DX will get control via a far CALL.

    On entry to your handler:
    AX contains a bit mask identifying which event has occurred (it is
    encoded in the same format as described for CX, above).

    BX contains the mouse button status:
    bit 0 = left button (BX & 1) == 1
    bit 1 = right button (BX & 2) == 2
    bit 2 = center button (BX & 4) == 4

    CX horizontal position (in text mode, divide by 8 for character clm)
    DX vertical position (in text mode, divide by 8 for character line)

    SI distance of last horizontal motion (mickeys: <0=left; >0=right)
    DI distance of last vertical motion (mickeys: <0=upward, >0=down)

    DS mouse driver data segment
    You will need to set up DS to access your own variables. You
    need not save/restore CPU registers, since the driver does this
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    for you.

    Exit your custom handler via a FAR RETurn (not an IRET).

    To enable or disable selected events for your handler, use this
    function again, passing a modified mask in CX. To disable all
    events for the handler, call this function again passing a value
    of 0000H in CX.

    Warning: You must disable your custom event handler (call with CX=0)
    before exiting to DOS. For TSRs, you must enable each time you
    pop up and disable each time you pop down.

    Notes: You may prefer to use the more-flexible INT 33H 0014H (exchange
    handlers) or INT 33H 0018H (install mouse+key handler).

    Вот и все. Ничего о сохранении.
     
  5. Пончик

    Пончик Гость

    Чесно говоря такие тонкости да ешё на англицком мне не по зубам
    , я тока начинаю начинать прошаривать в этом , но вот:

    .model tiny
    .code
    org 100h
    .186
    start:
    mov ax,3h
    int 10h
    mov ax,0
    int 33h
    mov ax,1
    int 33h
    mov ax,000ch
    mov cx,0002h
    mov dx,offset haha
    int 33h
    mov ax,0
    int 16h
    mov ax,000ch
    mov cx,0000h
    int 33h
    ret
    mesag db "left",0dh,0ah,'$'
    haha:
    mov ah,9
    mov dx,offset mesag
    int 21h
    retf
    end start
    Вот эта штука на чистом асме прет только так и в винде и в досе,
    поxоду дела это от того что прога комовская поэтому достаточно
    mov dx, offset haha
    В exe'шнои пришлось бы
    заносить в непосредственно
    в ES:DX
    Я прав как думаеш?
     
  6. Пончик

    Пончик Гость

    Всвязи с этим глупый вопрос -,как в es занести адрес данных?
     
  7. Пончик

    Пончик Гость

    Продолжение:
    в bp 7 такое не прокатывает:
    mov ax,codegroup
    mov es,ax
     
  8. Пончик

    Пончик Гость

    Да забыл спросить ,где взять полныи список прерываний BIOS'а?
    Кинь ссылку плз.
     
  9. Nevermind

    Nevermind Активный участник

    2.027
    0
    Относительно того, что прога работает из-за того, что используется модель tiny - вряд ли.
    Из-за особенностей данной модели значения всех сегментных регистров изначально равны, и PUSH CS/POP ES (или нечто подобное) не делается только потому, что нужное значение уже в ES. Различия, можно сказать, нет. Кстати, я, после того как в Pas'е обломался, сразу твой код в Асм забросил, и полужил те же глюки, только в другом флаконе (т.е. в .COM файле). Еще немного дегтя: прога у меня работает, но вместо сообщения выводит всякую хрень. Под отладчиком падает и вешает систему после нажатия кнопки мыши.

    Номер сегмента, ты хотел сказать?

    Cмотри мою первую мессагу. Вот два способа:

    mov ax,SEG @DATA ; для кода будет SEG @CODE
    Reg.es:=seg(MouseHandler); {NOTE: Reg - переменная типа Registers}


    Ссылку не кину, т.к. не знаю. Можно посмотреть на сайтах со сходной тематикой. Давно не искал материалы по Асму, т.к. стоящей информации в Инете не очень много. Вот первое, что пришло в голову: WWW.WASM.RU. Я там не был, но, может, чего интересного у них есть.

    Могу выслать "THELP!" - самый подробный DOS/BIOS хелп, который мне встречался, но он а) весит 1Мб б) На English'е. Есть, правда, и русская версия, но она не такая подробная (работал с ней мало, но, imo, она и рядом с THELP!'ом не стояла).
     
  10. Пончик

    Пончик Гость

    У меня таж история но работает устоичиво везде а муть выводит поxоду из за неопределенности
    местоположения селектора сегмента:-обработчик почемуто ишет в es ,а процедура в ds.
    Возникает вопрос огткель такая разница? ,тем более по умолчянию вроде ds тогда почему
    обработчик работает?
     
  11. Nevermind

    Nevermind Активный участник

    2.027
    0
    Хехе. Повторюсь:
    В .COM, можно сказать, вообще нет деления: Данные, стек и код находятся в одном сегменте.
    Поэтому все входные параметры установлены правильно.

    Далее, термин "селектор" применим только в Protected Mode.
    Там это - индекс в даблице дескрипторов. В реальном режиме сегмент - это способ получить доступ к большему объему памяти.
     
  12. Пончик

    Пончик Гость

    Сам не помну почему это слово написал ,знал же веть,
    вообщето я имел в виду что по умолчянию используеться ds(или es и т.д.)
    но здесь кажеться тот случаи когда нужна определённость
    т.е. в обработчике я пишу
    mov dx,offset proc и подразумеваю что занес адрес процедуры в es::dx
    а в процедуре пишу
    mov dx,offset string и подразумеваю что занес адрес строки в ds::dx
    между тем в моеи записи это не отражаеться- везде просто в dx заношу
    мне это кажеться странным и по меньшеи мере не понятно
    никак не могу прошарить.
     
  13. Nevermind

    Nevermind Активный участник

    2.027
    0
    Не в обработчике, а при установке обработчика. Обработчик -
    как раз процедура, адрес которой ты передаешь в ES: DX.

    Верно. Но здесь - DS=CS=ES, поэтому все без проблем.
    В .EXE бы ты возможно обломался в случае ES: DX, т.к. изначально ES может быть <> CS.

    Если я правильно понял, ты задаешь вопрос о том, почему при установке обработчика запись адреса идет в ES: DX, а при его работе в DS: DX ?

    Все зависит от того, в каких регистрах принимает параметры конкретная функция. Узнать это можно посмотрев документацию. Пример(не уверен насчет _всех_ функций для каждого инта):
    Для функций INT 33h адрес принимается в ES: DX;
    для функций INT 21h адрес DS: DX.
    для функций INT 13h - ES:BX
     
  14. Пончик

    Пончик Гость

    ДОШЛО наконец ,но остальное требует дальнеишего рассмотрения,
    (это я насчет мутни которую прога выводит вместо того чтот надо)
    да кстати я выяснил если в процедуре паскалевскои не завершать
    прогу ret'ом то она под досом нормально работает (тачка не виснет)
    но под виндои та же история и выводит муть по прежнему везде.
    Уже почти неделю над этим всем бошку ломаю
     
  15. Пончик

    Пончик Гость

    в этои теме уже на книжку инфы хватит.



    ложусь спать до 9-00
     
  16. Пончик

    Пончик Гость

    .model tiny
    .code
    org 100h
    .186
    start:

    mov ax,3h
    int 10h
    mov ax,0
    int 33h
    mov ax,1
    int 33h

    mov ax,000ch

    mov cx,0002h


    mov dx,offset haha

    int 33h
    mov ax,0
    int 16h
    mov ax,000ch

    mov cx,0000h
    int 33h
    ret
    mesage_1 db "MOUSE ERROR "
    mesage_1_length=$-MESAGE_1

    haha:
    mov ah,40h
    mov bx,2
    mov dx,offset mesage_1
    mov cx,mesage_1_length
    int 21h

    retf

    end start
    Попробуй если не лень вот эту прогу (тока на мыш надо раз 50 нажать после этого можно уловить как
    ие нибуть закономерности но мне это ничего не даст -я плохо шарю в асме)
     
  17. andrews

    andrews Участник

    153
    0
    народ, а что swapvectors в паскале уже отменили ? :-)
     
  18. Пончик

    Пончик Гость

    Хочу на асме
     
  19. Nevermind

    Nevermind Активный участник

    2.027
    0
    По поводу программы: работает так же неправильно, как и все остальные варианты.