WWW.ИСХОДНИКИ.РУ cpp.sources.ru
java.sources.ru web.sources.ru soft.sources.ru
jdbc.sources.ru asp.sources.ru api.sources.ru

  Форум на исходниках
  Pascal
  Обработка int 21h

СПРОСИТЬ  ОТВЕТИТЬ
профайл | регистрация | faq

Автор Тема:   Обработка int 21h
Man опубликован 28-11-2001 11:59 MSK   Click Here to See the Profile for Man   Click Here to Email Man  
Подкажите, как правильно обрабатывать int_21h в паскале. Вот пример простенькой проги, где собственный обработчик прерывания просто вызывает стандартную процедуру его обработки. При запуске программа виснет.
С прерываниями клавиатуры и таймера все работает, а вот 21 ... :(

{$M $800,0,0} { 2K stack, no heap }
uses Crt,Dos;
var
Int21Old: Procedure;

{$F+}
procedure NewInt21; interrupt;
begin
inline ($9C); { PUSHF -- Push flags }
Int21Old;
end;
{$F-}

begin
GetIntVec($21,@Int21Old);
SetIntVec($21,@NewInt21);
Keep(0);
end.

FisherMan опубликован 28-11-2001 13:50 MSK     Click Here to See the Profile for FisherMan  Click Here to Email FisherMan     
Ты вызываешь Int21Old по CALL а надо по JMP,
т.к. ты в стек уже засунул флаги. При возврате из int21 происходит неверный RET.
7in опубликован 28-11-2001 21:50 MSK     Click Here to See the Profile for 7in  Click Here to Email 7in     
Нет, JMP тут не поможет, всё равно повиснет, т.к. у тебя стоит директива interrupt (она в начале кода сохраняет в стеке регистры)!
Лучше попробуй после Int21Old записать...

inline($9C/ { pushf }
$8F/$46/$16); { pop word ptr [bp+16h]
}

Я не проверял, но работать должно!

И ещё... если перед Int21Old в стек ничего не записывается, твой inline($9C) лучше делать в начале процедуры.

7in опубликован 28-11-2001 22:58 MSK     Click Here to See the Profile for 7in  Click Here to Email 7in     
Блин, слушай, я прогнал немного...
Тут проблема не только в том, что флаги после Int21Old не сохраняются (для того, кто вызвал int 21h), а в том, что и регистры тоже не сохраняются! К тому же, оригинальному int 21h неверно передаются регистры ds и bp. Сделай тогда так...

{$S-} { Это важно! }
Procedure NewInt21;
Begin
Asm
push ds
push es
db 60h { pusha }
mov ax,seg @Data
mov ds,ax
End;
{ ...Твои процедуры... }
Asm
mov ax,word ptr Int21Old[0]
mov word ptr cs:@ofs,ax
mov ax,word ptr Int21Old[2]
mov word ptr cs:@seg,ax
db 61h { popa }
pop es
pop ds
pop bp { нужно потому, что процедура делает "push bp" в самом начале }
db 0EAh { jmp ssss:oooo }
@ofs: dw 0
@seg: dw 0
End
End;

И не забывай делать SwapVectors перед Keep!
-------------------------------------------

Кстати (это уже для FisherMan'а), pushf он делает потому, что iret вытаскивает 3 слова из стека (последний - как раз флаги), а retf (выход из процедуры) - всего 2, так что тут проблема не в этом...

Man опубликован 04-12-2001 10:17 MSK     Click Here to See the Profile for Man  Click Here to Email Man     
Облом!
Сделал, как написал "7in"...
Виснуть прога перестала, но процедура NewInt21 вызывается почему-то только 8 раз и все... Больше ей управление не передается :-(
7in опубликован 04-12-2001 23:21 MSK     Click Here to See the Profile for 7in  Click Here to Email 7in     
Пришли мне свою прогу на мыло eujin@mailru.com . Может, там другие глюки есть...

СПРОСИТЬ  ОТВЕТИТЬ
Перейти:


E-mail | WWW.ИСХОДНИКИ.RU

Powered by: Ultimate Bulletin Board, Freeware Version 5.10a
Purchase our Licensed Version- which adds many more features!
© Infopop Corporation (formerly Madrona Park, Inc.), 1998 - 2000.