Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.144.25.74] |
|
Сообщ.
#1
,
|
|
|
Подкажите, как правильно обрабатывать 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. |
Сообщ.
#2
,
|
|
|
Ты вызываешь Int21Old по CALL а надо по JMP,
т.к. ты в стек уже засунул флаги. При возврате из int21 происходит неверный RET. |
Сообщ.
#3
,
|
|
|
Нет, JMP тут не поможет, всё равно повиснет, т.к. у тебя стоит директива interrupt (она в начале кода сохраняет в стеке регистры)!
Лучше попробуй после Int21Old записать... inline($9C/ { pushf } $8F/$46/$16); { pop word ptr [bp+16h] } Я не проверял, но работать должно! И ещё... если перед Int21Old в стек ничего не записывается, твой inline($9C) лучше делать в начале процедуры. |
Сообщ.
#4
,
|
|
|
Блин, слушай, я прогнал немного...
Тут проблема не только в том, что флаги после 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, так что тут проблема не в этом... |
Сообщ.
#5
,
|
|
|
Облом!
Сделал, как написал "7in"... Виснуть прога перестала, но процедура NewInt21 вызывается почему-то только 8 раз и все... Больше ей управление не передается :-( |
Сообщ.
#6
,
|
|
|
Пришли мне свою прогу на мыло eujin@mailru.com . Может, там другие глюки есть...
|