精华区 [关闭][返回]

当前位置:网易精华区>>讨论区精华>>编程开发>>C/C++>>DOS编程>>DOS中断驻留框架(4/6)

主题:DOS中断驻留框架(4/6)
发信人: riffle()
整理人: wenbobo(2002-08-13 10:45:45), 站内信件
/* author : *** */
/*--------------------------------------------------------------------
--*/

// TSRINT.CPP

// 本模块和TEST.CPP、TSRINTER.CPP、TSR框架LIB一起做一个project,在larg
e或
// huge模式下编译生成EXE文件以后,就具有驻留及退出驻留的功能了。

#include <DOS.H>
#include <STDIO.H>
#include <STDLIB.H>
#include <PROCESS.H>
#include "INTFRAME.H"

/*--------------------------------------------------------------------
--*/

#ifdef __cplusplus
  #define __CPPARGS ...
#else
  #define __CPPARGS
#endif

/*--------------------------------------------------------------------
--*/

const int INT8 = 8;

/*--------------------------------------------------------------------
--*/

// 设置栈空间大小

extern unsigned int _stklen = 8192;

/*--------------------------------------------------------------------
--*/

// 保存旧的INT 8中断服务程序地址
static void interrupt ( *oldINT8Handler )( __CPPARGS );

static void SaveHardVector( void );
static int TsrCanExit( void );
static void IntA0CallBack( void );

static void testfunc( void );
/*--------------------------------------------------------------------
--*/
/*********************************************************************
***/
static void SaveHardVector( void )
{
  oldINT8Handler = getvect( INT8 );
}
/*********************************************************************
***/

/*********************************************************************
***/
static int TsrCanExit( void )
{
  if ( oldINT8Handler == getvect( INT8 ) )
    return 1;
 else
    return 0;
}
/*********************************************************************
***/

/*********************************************************************
***/
static void IntA0CallBack( void )
{
  // 进入中断时的功能号 AX == REMOVECMD,则退出驻留程序。
  if ( OldAX() == REMOVECMD )
    {
      // 准备退出驻留成功
      if ( PrepareExitTSR() )
        // 则调用 exit 退出整个程序
exit( EXIT_SUCCESS );
      else
        // 否则将AX设置成 -1,表示退出驻留失败。
SetReturnAX( 0xFFFF );
    }
  else
    {
      switch( OldAX() )
{
          // 检查是否已经安装?
  case CHECKINTCMD:
            // 设置 AX 内容为安装标志。
    SetReturnAX( INSTALLEDSIGN );
    break;
  case 0x00F0:
            // AX == 0X00F0 测试一下,可以用 DEBUG 进行试验。
    testfunc();
    break;
          default:
    break;
       }
   }
}
/*********************************************************************
***/

/*********************************************************************
***/
int Install( void )
{
  unsigned int *uipKeepSize;
  // DOS程序执行时,PSP所在段的段值减去1就是其MCB段址。
  // MCB的地3,4字节表示该MAB的节(16字节)数。
  uipKeepSize = ( unsigned int * )MK_FP( _psp - 1, 3 );
  // 先记住INT 8的中断向量,这里是假设本程序需要使用INT 8中断服务程序。

  // 当然也可以不在本模块中检查,而在使用INT 8的模块中的安装中断向量的

  // 函数中登记类似TsrCanExit的函数。
  SaveHardVector();

  // 登记退出检查函数。该函数判断该驻留程序是否可以退出。
  // 最多可以登记16个退出检查函数。
  if ( RegisterExitCallBack( TsrCanExit ) )
    {
      // 设置所用软中断的中断号以及中断服务程序回调函数。
      // 汇编模块中的中断服务程序将调用IntA0CallBack回调函数。
      SetVector( INTERFACEINT, IntA0CallBack );

      // 驻留(驻留程序占用的内存由当时的MCB决定)。
      // 程序在keep之前应初始化好所有数据结构,其中包括需要使用new分配
内存的情况。
      // 因为C程序(for dos)启动后,其所有的内存都在该进程拥有的MCB管辖
之下,其中
      // 高端是堆区,并且还事先预留了大约1K的空间给new(或其他内存分配函
数,下同)
      // 使用,如果new申请的内存比较大,程序将调用INT 21的4AH功能调整M
CB所管辖的
      // MAB大小,当然,这同时还要求DOS内核记录的当前PSP跟MCB的所有者(
Owner)PSP
      // 一致,不然,调用完INT 21以后,该MCB的Owner就会改成当前PSP了。
举个例子:
      // 本程序使用的是软中断INT A0,驻留以后,另外一个程序(假设为APP吧
)调用INT A0
      // 的某项服务,而INT A0中断服务程序在提供该项功能时没有切换PSP,
并且使用new
      // 分配较大内存,导致调用了INT 21的4A号功能,那么该MCB的Owner就被
换成了APP了,
      // 并将随着APP的退出而被整个释放!
      // 从这里也可以看出,驻留以后是在也不能使用new的,除非再截获INT 
21的4A号功能,
      // 作些支持。
      keep( 0, uipKeepSize[ 0 ] );
      //这句已经没有意义,只是为了消除警告用的。
      return 1;
    }
  else
    //登记失败,返回0
    return 0;
}
/*********************************************************************
***/

/*********************************************************************
***/
static void testfunc( void )
{
  char s[ 500 ];
  s[ 499 ]  = 3;
  printf( "%p\n", &s[ 0] );
}
/*********************************************************************
***/
/*********************************************************************
***/
/*********************************************************************
***/

--
※ 来源:.月光软件站 http://www.moon-soft.com.[FROM: 202.104.39.56]

[关闭][返回]