· Начало · Отвђтить · Статистика · Поиск · FAQ · Правила · Установки · Язык · Выход · WASM.RU · Noir.Ru ·

 WASM Phorum —› WASM.ASSEMBLER —› Вопрос повторной входимости

Посл.отвђт Сообщен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