Автор
|
Тема: Обработка int 21h
|
Man |
опубликован 28-11-2001 11:59 MSK
Подкажите, как правильно обрабатывать 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
Ты вызываешь Int21Old по CALL а надо по JMP, т.к. ты в стек уже засунул флаги. При возврате из int21 происходит неверный RET. |
7in
|
опубликован 28-11-2001 21:50 MSK
Нет, JMP тут не поможет, всё равно повиснет, т.к. у тебя стоит директива interrupt (она в начале кода сохраняет в стеке регистры)! Лучше попробуй после Int21Old записать...inline($9C/ { pushf } $8F/$46/$16); { pop word ptr [bp+16h] } Я не проверял, но работать должно! И ещё... если перед Int21Old в стек ничего не записывается, твой inline($9C) лучше делать в начале процедуры. |
7in
|
опубликован 28-11-2001 22:58 MSK
Блин, слушай, я прогнал немного... Тут проблема не только в том, что флаги после 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
Облом! Сделал, как написал "7in"... Виснуть прога перестала, но процедура NewInt21 вызывается почему-то только 8 раз и все... Больше ей управление не передается :-( |
7in
|
опубликован 04-12-2001 23:21 MSK
Пришли мне свою прогу на мыло eujin@mailru.com . Может, там другие глюки есть... |