[identity profile] edson86.livejournal.com posting in [community profile] useful_faq
Я пишу программу-резидент... Но она постоянно выдаёт сообщение о том, что выполнена недопустимая инструкция... Помогите найти ошибку....
Я думаю ошибки где-то в процедурах обработки прерываний от таймера (Int1Ch_proc) и обработки 21-ого прерывания.... Помогите найти ошибку...

Вот процедуры из моей программы -

Int_21h_proc proc far

test cs:[MyFlags],bActivityFlag
jnz Go_21h

pushf

or cs:[MyFlags],bActivityFlag

cmp ax,9889h ;Проверка на повторную загрузку
jne Goo_21h

xchg ah,al ;Если мы уже в перехватывает прерывание, то
popf

and cs:[MyFlags], (not bActivityFlag)

iret ;меняем регистры
Goo_21h:

popf
and cs:[MyFlags], (not bActivityFlag)

jmp dword ptr cs:[Int_21h_vect] ;передаем управление
;оригинальному обработчику 21h

Go_21h:

jmp dword ptr cs:[Int_21h_vect] ;передаем управление
;оригинальному обработчику 21h

Int_21h_vect dd ? ;адрес оригинального абработчика
Int_21h_proc endp

Int_1Ch_proc proc far

pushf
call dword ptr cs:[Int_1Ch_vect] ;вызов оригинального обработчика

test cs:[MyFlags],bActivityFlag ;проверим флаг активизации резидента
jz Not_active

iret ;активирован выходим

Not_active:

test cs:[MyFlags],bCallFlag ;проверим флаг вызова резидента
jnz callVideo

or cs:[MyFlags],bActivityFlag ;установим флаг активации резидента

mov al, 20h ;сбросим контроллер прерываний
out 20h, al

call MyResident ;вызываем резидентную процедуру

and cs:[MyFlags], (not bActivityFlag) ; сбросим флаг активации

iret ;выходим


CallVideo:

or cs:[MyFlags],bActivityFlag ;установим флаг активации резидента

mov al, 20h ;сбросим контроллер прерываний
out 20h, al

call Smena_Stranici ;вызываем резидентную процедуру

and cs:[MyFlags], (not bCallFlag) ; сбросить флаг вызова
and cs:[MyFlags], (not bActivityFlag) ; сбросим флаг активации

iret ;выходим

Int_1Ch_vect dd ? ;адрес оригинального абработчика
Int_1Ch_proc endp

Int_10h_proc proc far
pushf

or cs:[MyFlags],b10hFlag ;Устанавливаем флаг VideoBios

test cs:[MyFlags],bActivityFlag ;проверяем флаг активации резидента
jz No_Active

cmp ah,05h

jne No_Active

mov ax,0501h

and cs:[MyFlags],(not b10hFlag)

No_Active:
popf

call dword ptr cs:[Int_10h_vect] ;вызов оригинального обработчика



Int_10h_vect dd ? ;адрес оригинального абработчика
Int_10h_proc endp

Int_09h_proc proc far

pushf

test cs:[MyFlags],bActivityFlag ;проверим флаг активации резидента
jnz Exit_09h ;если активирован - выходим из обработчика

pusha ;Сохраним регистры в стеке...

in al,60h ;Получим СКАН-КОД нажатой клавиши.
mov ah,al
and al,7fh ;al - чистый скан-код без признака нажатия

cmp al,03h ; 2?
jnz Exit_09h

in al, 61h ;посылаем подтверждение контроллеру
push ax ;клавиатуры
or al, 80h
out 61h,al
pop ax
out 61h,al

or cs:[MyFlags], bCallFlag ;установим флаг вызова

mov al, 20h ;сбросим контроллер прерываний
out 20h, al

popa
popf

iret

Exit_09h:

popf
jmp dword ptr cs:[Int_09h_vect] ;вызов оригинального обработчика


Int_09h_vect dd ? ;адрес оригинального абработчика
Int_09h_proc endp

Smena_Stranici proc

pushf

or cs:[MyFlags],b10hFlag ;Устанавливаем флаг VideoBios

test cs:[MyFlags],bActivityFlag ;проверяем флаг активации резидента
jz No_Activee

mov ax,0500h

and cs:[MyFlags],(not b10hFlag)

No_Activee:
popf

call dword ptr cs:[Int_10h_vect] ;вызов оригинального обработчика


ret
Smena_Stranici endp

MyResident proc

pusha
push es
push ds

push 0b800h
pop ds

push 0b900h
pop es

xor si,si
mov cx,2000

Next_sym:
mov di,si

lodsw
cmp al,' '
je Next_byte

;mov ah,0fh
mov al,1
stosw

Next_byte:

loop Next_sym

pop ds
pop es
popa



ret
MyResident endp

Открой для себя тэг ...

Date: 2005-05-07 01:21 pm (UTC)
From: [identity profile] poige.livejournal.com
<code>

Date: 2005-05-07 03:09 pm (UTC)
From: [identity profile] egorfine.livejournal.com
Что-то я не понимаю.. двадцатьпервое прерывание... вы че, под ДОС пишете резидента, что ли? :-))))

Date: 2005-05-07 04:00 pm (UTC)
From: [identity profile] netp-npokon.livejournal.com
Написание резидентов под Windows имеет скорее медитативный смысл %)

Date: 2005-05-07 04:59 pm (UTC)
From: [identity profile] egorfine.livejournal.com
Ну а под дос - вообще никакого.

Date: 2005-05-09 04:57 pm (UTC)
From: [identity profile] eugene-ivanov.livejournal.com
обычно в этих случаях говорят - ошибка в генах ;)

Date: 2005-05-09 04:59 pm (UTC)
From: [identity profile] eugene-ivanov.livejournal.com
да. он на rusfaq.ru уже своим вопросом всё обвесил ;) так ещё и тут думает, что за него будут всё решать ;)

Date: 2005-05-09 05:01 pm (UTC)
From: [identity profile] eugene-ivanov.livejournal.com
друг. у тебя тут одна ошибка за другой. научись сначала постепенно писать программы, и постепенно их же запускать.
и изучи сначала другие исходники и справку.

пришли мне все исходники на gmail - Eugene.Ivanov я там.
я тебе помогу.

Date: 2005-05-09 05:13 pm (UTC)
From: [identity profile] eugene-ivanov.livejournal.com
сразу могу сказать
  • в обработчике 1С прерывания не нужно сбрасывать контроллер прерываний.
  • вызывать другие обработчики нужно командой
    pushf+call
  • не обязательно работать по порту 97
    можно сделать обработчик вот по такой схеме:
    int_09h_entry:

    exit_9:
    db 234
    old_9 dd 0
  • подтверждение контроллеру клавиатуры делать вот так!
    in al,97
    or al,128
    out 97,al
    and al,127
    out 97,al
    потому что ты не знаешь, был там бит установлен или нет ;)
  • после этой метки Exit_09h:
    поставь popa

ну и так далее.. вроде ошибок явных не вижу больше..
но всё равно - будь аккуратен! и перед такими криками о помощи сначала САМ поищи чисто ошибки по невнимательности.

Удачи!

Date: 2005-05-11 10:55 am (UTC)
From: [identity profile] ayl.livejournal.com
Да у него еще куча ошибок! 10-е прерывание вообще все наперекосяк.
А насчет 61-го порта... Когда вызывается 9-е прерывание, старший бит сброшен. Если мне нужно послать подтверждение КК о принятии символа, я его устанавливаю, а потом сбрасываю. Каким образом он может оказаться несброшенным при его чтении из порта? Только если нерадивый программист встроил свой обработчик, не сбрасывающий этот бит, перед моим. Согласен, такое теоретически может быть, но маловероятно.
А в принципе, абсолютно по барабану, как сбрасывать этот бит - вручную или через сохраненное значение.

Date: 2005-05-11 12:37 pm (UTC)
From: [identity profile] eugene-ivanov.livejournal.com
я много раз накадывался. у меня почему-то зависала клава..а потом сделал вот так - и всё путём.
да и вообще привык я всё делать надёжно.чтобы не было сомнений и ни от кого не зависеть !