首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C语言 >

各位C程序员大大们请进.该如何解决

2012-02-12 
各位C程序员大大们请进...急!!偶在学习DOS6.22下的TSR,开发工具为TC3.0,请教高手们一个问题:怎么做才可以

各位C程序员大大们请进...急!!
偶在学习DOS6.22   下的TSR,开发工具为TC3.0,请教高手们一个问题:

怎么做才可以接管21H中断?常规方法好象是不行的,一运行就死机/花屏。。


方法一:

#include   <dos.h>
typedef   void   interrupt   (   *TInt   )();
TInt   Old21   =   0;
void   interrupt   MyInt21()
{
//   ....
(     *Old21   )();
}

void   install   ()   /*安装中断*/
{
disable();
setvect(   0x21,   MyInt21   );            
                enable();
}

int   main()
{      
OldInt   =   getvect(   0x21   );
install();
keep(0,_SS+_SP/16-_psp);
                return   0;
}

方法二:

#include   <dos.h>


typedef   void   interrupt   (   *TInt   )();
typedef   int   far   *FPInt;
FPInt   MySeg   =   0;
FPInt   MyOff   =   0;
TInt   OldInt   =   NULL;
FPInt   Vect21   =   NULL;

void   interrupt   MyInt21()
{
//   ....
(     *OldInt   )();
}

void   install   ()   /*安装中断*/
{
disable();
MyOff   =   (   fpint   )MyInt21;
MySeg   =   (   fpint   )_cs;
vect21   =   MK_FP(   0x00,   4   *   0x21   );     //   vector   21h
                *vect21++   =     myint21;
                *vect21   =   MySeg   ;
               
                //*vect21   =   mk_fp(   myseg,   myoff   );

                enable();

}

int   main()
{      
OldInt   =   getvect(   0x21   );
install();
keep(0,_SS+_SP/16-_psp);
                return   0;
}


问题:   这两种做法替换14H中断时,都没问题,但21H就不行,请问大家在替换INT21时需要注意哪些事情?21H是系统中断,我刚刚接触这方面,不是很懂,请大家多多帮忙!

[解决办法]
1.工程使用Large内存模式,或者
2.加上far修饰:
typedef void (interrupt far *TInt)();
void interrupt far MyInt21() {...}

如果还不行,把编译器产生的汇编代码中的MyInt21函数部分发出来我看看。
[解决办法]
在原中断返回后你的程序也不能破坏现场应立即返回给原始调用者,也就是说
:0001.0369 50 PUSH AX
:0001.036A 53 PUSH BX
:0001.036B 51 PUSH CX
:0001.036C 52 PUSH DX
:0001.036D 06 PUSH ES
:0001.036E 1E PUSH DS
:0001.036F 56 PUSH SI
:0001.0370 57 PUSH DI
:0001.0371 55 PUSH BP
:0001.0372 2E8B2E6503 MOV BP, CS:[0365]
:0001.0377 8EDD MOV DS, BP
:0001.0379 8BEC MOV BP,SP
:0001.037B 9C PUSHF
:0001.037C FF1E620D CALL FAR WORD PTR [0D62]
:0001.0380 50 PUSH AX
:0001.0381 B88219 MOV AX, 1982
:0001.0384 58 POP AX
:0001.0385 5D POP BP
:0001.0386 5F POP DI
:0001.0387 5E POP SI
:0001.0388 1F POP DS
:0001.0389 07 POP ES
:0001.038A 5A POP DX
:0001.038B 59 POP CX
:0001.038C 5B POP BX
:0001.038D 58 POP AX
:0001.038E CF IRET

的倒数的二行pop ax已经破坏了原中断的返回值

热点排行