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?Может есть тот чел которыи разбереться?
ХЗ. Для начала баг: Данная ф-я (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 ************************* Что-то не тянет это на обработчик. В чем дело?
Перед установкой - нет. Перед обработчиком - тоже нет. Приведу кусок хелпа: 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). Вот и все. Ничего о сохранении.
Чесно говоря такие тонкости да ешё на англицком мне не по зубам , я тока начинаю начинать прошаривать в этом , но вот: .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 Я прав как думаеш?
Относительно того, что прога работает из-за того, что используется модель 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!'ом не стояла).
У меня таж история но работает устоичиво везде а муть выводит поxоду из за неопределенности местоположения селектора сегмента:-обработчик почемуто ишет в es ,а процедура в ds. Возникает вопрос огткель такая разница? ,тем более по умолчянию вроде ds тогда почему обработчик работает?
Хехе. Повторюсь: В .COM, можно сказать, вообще нет деления: Данные, стек и код находятся в одном сегменте. Поэтому все входные параметры установлены правильно. Далее, термин "селектор" применим только в Protected Mode. Там это - индекс в даблице дескрипторов. В реальном режиме сегмент - это способ получить доступ к большему объему памяти.
Сам не помну почему это слово написал ,знал же веть, вообщето я имел в виду что по умолчянию используеться ds(или es и т.д.) но здесь кажеться тот случаи когда нужна определённость т.е. в обработчике я пишу mov dx,offset proc и подразумеваю что занес адрес процедуры в es:x а в процедуре пишу mov dx,offset string и подразумеваю что занес адрес строки в ds:x между тем в моеи записи это не отражаеться- везде просто в dx заношу мне это кажеться странным и по меньшеи мере не понятно никак не могу прошарить.
Не в обработчике, а при установке обработчика. Обработчик - как раз процедура, адрес которой ты передаешь в 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
ДОШЛО наконец ,но остальное требует дальнеишего рассмотрения, (это я насчет мутни которую прога выводит вместо того чтот надо) да кстати я выяснил если в процедуре паскалевскои не завершать прогу ret'ом то она под досом нормально работает (тачка не виснет) но под виндои та же история и выводит муть по прежнему везде. Уже почти неделю над этим всем бошку ломаю
.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 нажать после этого можно уловить как ие нибуть закономерности но мне это ничего не даст -я плохо шарю в асме)