|
|
| Посл.отвђт | Сообщенiе |
|
|
Дата: Июн 4, 2003 09:28:09 Написал программу состаящую из менюшки и таймера. и то и другое реализовано с помощью перехвата прерываний. внутри моих процедур обработки я работал на уровне портов и все было хорошо, пока я не наткнулся на несколько ф-й реализованых только прерываниями ДОС. если их вставить внутрь процедуры перехвата прерываний они весят машину. Насколько я смог понять из документации причина этого в том что ф-и ДОС и БИОС лишены повторной входимости (или я опять все напутал и не так понял?). Та же документация в качестве решения предлагает "избегать повторной входимости". Собственно я не могу найти замену 2 ф-ям. Ф-и завершения программы mov ah,4ch int 21h и запуска... 4bh Тело программы непосредственно состоит из установки моих обработчиков прерываний и пустого цикла. Можно конечно в прерывании записывать 1 в переменную - индикатор и в цикле постоянно ее проверять, но это имхо некрасиво и я подозреваю очень не рационально... Подскажите пожалуста как с этим бороться. С надеждой на вашу помощь. Ворон. Листинг: dosseg .386 stacks segment stack 'STACK' use16 db 100h dup (?) stacks ends codes segment 'code' use16 assume cs:codes,es:datas,ds:datas begin: mov bp,offset PSP mov [bp],es mov bx,stacks add bx,(100h+15)/16 mov ax,[bp] sub bx,ax mov ah,4ah int 21h mov ah,00h mov al,03h int 10h call DrawMain mov ax,seg pr mov ds,ax mov ah,35h mov al,09h int 21h mov bp,offset oldkeyoff mov ds:[bp],bx mov bp,offset oldkeyseg mov ds:[bp],es mov ah,25h mov al,09h mov dx,offset key_handler int 21h loopit: jmp loopit codes ends pr segment 'pr' use16 assume cs:pr DrawMain proc far push es push di push ax push cx push es push 0b800h pop es push 0530h pop di mov ax,seg datas mov ds,ax mov ax,offset op1 mov si,ax mov cx,op1l mov al,dark cmp ds:stat,01h jne dark1 mov al,light dark1: o1: movsb stosb dec cx jne o1 add di,0a0h sub di,op1l sub di,op1l mov ax,seg datas mov ds,ax mov ax,offset op2 mov si,ax mov al,dark mov cx,op2l cmp ds:stat,02h jne dark2 mov al,light dark2: o2: movsb stosb dec cx jne o2 add di,0a0h sub di,op2l sub di,op2l mov ax,seg datas mov ds,ax mov ax,offset op3 mov si,ax mov cx,op3l mov al,dark cmp ds:stat,03h jne dark3 mov al,light dark3: o3: movsb stosb dec cx jne o3 pop es pop cx pop ax pop di pop es ret DrawMain endp key_handler proc far push es push di push ax push ds push cs pop ds mov ax,seg datas mov ds,ax in al,60h cmp al,49h je uparrow cmp al,51h je downarrow cmp al,01h je exitkey cmp al,1ch je enterkey jmp over enterkey: cmp ds:stat,03h je exitkey cmp ds:stat,01h jne next0 mov bp,offset oldkeyseg mov ax,ds:[bp] mov ds,ax mov bp,offset oldkeyoff mov dx,ds:[bp] mov ah,25h mov al,09h int 21h mov ax,seg datas mov es,ax mov ax,seg datas mov ds,ax mov ax,4b00h mov dx,offset way1 mov bx,offset EPB int 21h mov ax,seg pr mov ds,ax mov ah,35h mov al,09h int 21h mov bp,offset oldkeyoff mov ds:[bp],bx mov bp,offset oldkeyseg mov ds:[bp],es mov ah,25h mov al,09h mov dx,offset key_handler int 21h jmp over next0: jmp over exitkey: mov bp,offset oldkeyseg mov ax,ds:[bp] mov ds,ax mov bp,offset oldkeyoff mov dx,ds:[bp] mov ah,25h mov al,09h int 21h mov ah,4ch int 21h uparrow: cmp ds:stat,01h jne up2 mov ds:stat,03h call DrawMain jmp over up2: cmp ds:stat,02h jne up3 mov ds:stat,01h call DrawMain jmp over up3: cmp ds:stat,03h jne up4 mov ds:stat,02h call DrawMain jmp over up4: jmp over downarrow: cmp ds:stat,01h jne down2 mov ds:stat,02h call DrawMain jmp over down2: cmp ds:stat,02h jne down3 mov ds:stat,03h call DrawMain jmp over down3: cmp ds:stat,03h jne down4 mov ds:stat,01h call DrawMain jmp over down4: jmp over over: pop ds pop ax pop di pop es db 0eah; oldkeyoff dw ? oldkeyseg dw ? iret key_handler endp pr ends datas segment 'DATA' use16 op1 db "option1" op1l equ $-op1 op2 db "option2" op2l equ $-op2 op3 db "exit" op3l equ $-op3 light equ 00001010b dark equ 00000010b stat db 03h way1 db "e:\asm\work\c.exe",0 EPB dw 0000 dw 0000 dw 0000 PSP db (?) exstat db 01h text db 80 dup (?) datas ends end |
|
|
Дата: Июн 4, 2003 09:43:02 Флаг устанавливать все таки придется, по другому никак. Или можно завести переменную в которой будет хранится указатель на пустую процедуру. А когда прерывание сработает, запишем туда указатель на процедуру для завершения/запуска программы. Хотя можно еще тестить флаг занятости доса, вешать дополнительный обработчик для предотвращения повторного входа в биос, но по моему эти методы еще более уродливы, чем опрос флага в бесконечном цикле. |
|
|
Дата: Июн 4, 2003 09:54:25 Существует прерывание int 28h, которое дос вызывает, когда он не занят. По крайней мере я его использовал для записи из резидента: ; Инсталляция VectorDosFlag equ 28h ; Set new int 28h handler mov ax,(35H shl 8) + VectorDosFlag int 21h ; Get old HookedVector to es:bx mov word ptr ds:Old28hHandler,bx mov word ptr ds:Old28hHandler+2,es mov dx,offset @@NewInt28Handler mov ah,25h int 21H ; Set new Vector ; Адрес занятости dos_addr получается через ; ф-цию ah=~34h int 21h @@NewInt28Handler: pusha push ds push es push cs pop ds ; Check DOS flag lds di,ds:dos_addr cmp byte ptr ds:[di+1],1 ja @@DosIsBusy ; Типа запись или что-то еще ... ; Restore regs and jump pop es pop ds popa jmp dword ptr cs:Old28hHandler Но оно тоже же не всегда готово... Лучше уж взводить в обработчике флаг и писать где-то рядом цикл, анализирующий флаг... |
|
|
Дата: Июн 4, 2003 10:12:11 · Поправил: P2M Raven Чем вообще занимается Ваша программа? Зачем Ей захватывать int9h? Насколько я понял достаточно в цикле опрашивать клавиатуру (int16h AH=01h и AH=00h)? |
|
|
Дата: Июн 5, 2003 10:55:53 Всем спасибо за ответы. Остановимся на флагах... Проверять занятость дос/биос конечно можно но в результате отзываться будет опять на "каждый десятый" клик, а это грусно... 2P2M: чем занимаеться моя программа? Правильнее будет спросить чем занимаюсь я. А я занимаюсь тем, что пытаюсь научиться кодировать на асме. Кодировать хорошо. Я уже пробыват опрашивать клавиатуру так как это предложил ты. Работает. Решил теперь так попробывать. Кроме того меня интересует есть ли в асме понятие "красивого" кода. Если есть, то помоему такой код "более" красивый... или я неправ? (как тогда стоит писать?) К стате - возникает вопрос что предпочтительнее и на что стоит ориентироваться: на работу с дос - биос ф-ями или на роботу с устройствами на уровне портов. Второе имхо дает больший контроль над кодом и понимание процесса... напишите, если я ошибаюсь, в чем и как правильно. С благодарностью за внимание и понимание. Ворон. |
|
|
Дата: Июн 5, 2003 12:02:22 Raven пробыват опрашивать клавиатуру ... Работает... Решил теперь так попробывать Не ищем легких путей? Если появилось желание исследовать Int9h, то можно было озадачиться, например, ведением лога клавиатуры. помоему такой код "более" красивый Для меня "красивый код" - это код, который прост в сопровождении = достаточность + переносимость + читаемость. на что стоит ориентироваться Для души или как? |
|
|
Дата: Июн 5, 2003 16:02:54 ***Для души или как?*** - ага для души... :) Но а вообще методы работы с устройствами зависят от задачи? (т.е. в одних случаях целесообразнее использовать ф-и биос-дос, а в других работу с портами или эти методы являються "ступенями". т.е. когда научился работать с ф-ями дос учишься работать с портами, а когда научился работать с портами ф-и дос становяться ненужными?) |
|
|
Дата: Июн 5, 2003 16:25:43 > ...ф-и дос становяться ненужными?) Вначале я тоже так думал и стремился все делать "сам": драйвер мыши и т.п. На самом деле в хороших api (dos, win...) нет ничего плохого, в конце концов приходишь к такому выводу. Но иногда бывает так, что лучше все сделать самому (прочесть нестандартно винт, рисовать графику на 286-ой машине и т.п.). |
|
Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.119 |