home *** CD-ROM | disk | FTP | other *** search
/ Phoenix CD 2.0 / Phoenix_CD.cdr / 24b / microc.zip / CING-38.FIG next >
Text File  |  1987-10-28  |  5KB  |  124 lines

  1.  
  2. /**************************************************************************/
  3. Figure 1 - In-Line Assembly Code for exec() Function
  4.  
  5. #pragma inline
  6. /**************/
  7. exec(char *program, char *argument)  /* new ANSI way of declaring args */
  8. {
  9. /*  The rules of this game are rather too involved to explain here.  See
  10.     Ray Duncan's <i>Advanced MSDOS<d>, chapter 10, for a lucid explanation
  11.     of the MSDOS's ``exec'' function. This is done in the ``large'' model so
  12.     pointers will all be 4 bytes long and coding will be straightforward.*/
  13. char comline[30];                   /* to construct command line */
  14. struct{                         /* structure needed by DOS 0x4b service */
  15.    unsigned envseg;
  16.    char *command,*fcb1,*fcb2;
  17.    } paramblock,*pbptr;
  18.  
  19. paramblock.envseg=0;              /* keep the old environment */
  20. comline[0] = strlen(argument);    /* first char: length of line */
  21. strcpy(comline+1,argument);
  22. strcat(comline,"\r");             /* terminate with 0xd */
  23. paramblock.command = comline;
  24. paramblock.fcb1=paramblock.fcb2=(char *)0xffffffff; /* Ignore fcb's */
  25. pbptr = ¶mblock;
  26. asm push ds         /* DS & BP must be saved. Turbo saves SI & DI */
  27. asm push bp
  28. /* The next two routines work because this is the LARGE model and
  29.    pointers are 32-bit entities and work with lds & les. Cute, no? */
  30. asm lds dx,program               /* DS:DX pointed to program path */
  31. asm les bx,pbptr                 /* ES:BX pointed to parameter structure */
  32. asm  mov word ptr cs:fill[0],ss  /* save SS & SP */
  33. asm  mov word ptr cs:fill[2],sp
  34. asm  jmp next
  35. asm  fill dw 0,0                 /* store SS & SP in code segment */
  36. next:
  37. asm  mov al,0
  38. asm  mov ah,4bh
  39. asm  int 21h                     /* do exec call */
  40. asm  cli
  41. asm  mov ss,cs:fill[0]           /* restore SS & SP */
  42. asm  mov sp,cs:fill[2]
  43. asm  sti
  44. asm  pop bp
  45. asm  pop ds
  46. }
  47. /*******************************************************************/
  48.  
  49.  
  50.  
  51.  
  52. /*Figure 2 - Getting Rid of Resident Programs*/
  53.  
  54. /* LARGE MODEL USED SO POINTERS ARE 32 BITS.
  55. This compiles to 5.6K, which supports Borland's claim to
  56. relatively tight code. Incidentally, I can do the same in 2.3K in DeSmet C
  57. and about 1K in assembler. Neither coding is half so simple, however.
  58. This sort of direct manipulation of MSDOS allocation headers
  59. is an example of ill-behaved programming at its most incorrigible. But don't
  60. long C pointers make crime EASY??*/
  61.  
  62. #include <dos.h>
  63. #include <stdio.h>
  64. #define RSHIFT   1     /* corresponding bits on shift state byte @ 00:417H */
  65. #define LSHIFT   2
  66. #define ALT      8
  67. #define TESTIT   (RSHIFT | LSHIFT | ALT)
  68. #define TICKINT  8
  69. #define NEWTICK  0x80
  70. #define FINI     0x5a
  71. char intable[0x400],*shiftptr=(char *) 0x417L;
  72. typedef struct {          /* MSDOS allocation header format */
  73.     char flag;        /* Either 5Ah for end or 4Dh for not end */
  74.     unsigned nextpsp,paragraphs;
  75.    } HEAD;
  76. HEAD *header;
  77. extern unsigned _psp;
  78. unsigned meminstall;    /* how much memory is installed in PC? */
  79. /******************/
  80. void interrupt tickhandler()
  81. {   /* check shift state for three shifts depressed */
  82.  
  83. if( (*shiftptr & TESTIT) == TESTIT) deallocate();
  84. geninterrupt(NEWTICK);  /* chain the interrupt */
  85. }
  86. /***************/
  87. deallocate()
  88. {
  89. HEAD *nextheader;
  90.  
  91. /* _AX is a "pseudovariable" which can be used to get or change
  92.   the value stored in AX. The possibilities are mind-boggling. */
  93. _AX=0xe00+7;               /* just a beep to show something happened */
  94. geninterrupt(0x10);
  95. memcpy(NULL,intable,0x400);  /* restore old int table */
  96. nextheader = MK_FP(_psp + header->paragraphs,0);
  97. nextheader->flag = FINI;  /* tell MSDOS that everything's free above */
  98. nextheader->nextpsp = 0;
  99. nextheader->paragraphs = meminstall - 1 - _psp - header->paragraphs;
  100. }
  101. /*********************/
  102. main()
  103. {
  104. char **newtick,**oldtick; /*just so it's 32 bits. char * is a convenience. */
  105.  
  106. header  = MK_FP(_psp - 1, 0); /* point to TSR's allocation header */
  107. newtick = MK_FP(0,4*NEWTICK);     /* swap interrupt vectors */
  108. oldtick = MK_FP(0,4*TICKINT);
  109. disable();                       /* stop hardware */
  110. *newtick = *oldtick;
  111. *oldtick = (char *) tickhandler;  /* put interrupt address into table */
  112. enable();
  113. memcpy(intable,NULL,0x400);      /* save old interrupt table */
  114. geninterrupt(0x12);              /*how much memory installed? */
  115. meminstall = _AX*0x40;           /* store amount in paragraphs */
  116. /* Note that TurboC concatenates strings for you. */
  117. puts("\nDEINSTALLATION PROGRAM INSTALLED\n"
  118.      "     Press Alt-Leftshift-Rightshift\n"
  119.      "to deinstall subsequent resident programs.\n" );
  120. keep(0,_SS - _psp +1);       /* lop off stack, terminate & stay...*/
  121. }/* keep(0,n) uses DOS function 31h to set aside n paragraphs of memory */
  122. /********************/
  123.  
  124.