home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / PROGRAMS / UTILS / DOS_HELP / STACKINF.ZIP / STACK
Encoding:
Text File  |  1988-05-12  |  5.4 KB  |  163 lines

  1. In article <539@siemens.UUCP>, jrv@siemens.UUCP (James R Vallino) writes:
  2. > In article <2045@optilink.UUCP> elliott@optilink.UUCP (Paul Elliott x225) writes:
  3. > >I am doing some TSR stuff using Microsoft C 5.0, and would like to
  4. > >get access to the SS and SP registers (to set up a local stack).
  5. > >TurboC has psuedo-variables for all the registers, and it is pretty
  6. > >simple to read and write to these and do what I want (in TutboC).
  7. > I had the same wish and could not find a way to set up a local stack short
  8. > of some assembly code. I punted and took the risk of using whatever stack
  9. > is active when the TSR is entered. So far that has worked but I would be
  10. > wary of not putting in the stack swap for a general use TSR.
  11.  
  12. That's a bad risk in my experience.
  13.  
  14. I have successfully managed stack swapping -- you are right, assembler is
  15. the only way.  At the end of this I will include the source code, NO
  16. GUARENTEES -- this works for me, but it's by no means foolproof.
  17.  
  18. You'd better swap stacks or you might get in real deep stuff.  You should
  19. realize that if you don't swap stacks, you should compile so that the code
  20. knows that DS<>SS when its compiling your routine.  This is accomplished
  21. with a -Aw (FLAME ON:  WHY DOES MICROSOFT INSIST ON CASE SENSITIVE COMMAND
  22. LINE OPTIONS.  FLAME OFF -- I feel better ), as in "cl -Od -AL -Aw foo.c". 
  23. Without this, I had several bizarre problems like code hanging on the
  24. statement "x = y".   
  25.  
  26. Even with this option, however, you must realize that almost all of the C
  27. runtime libraries are compiled to work only if DS=SS (I had originally
  28. written iff but MS bugs made me change the wording), and you can't really
  29. be sure whether or not the routine you want will cause a bizarre hangup. 
  30. For example, ctime() uses the stack partially -- in my example, I simply
  31. printed the current time, and it came out as partially correct, and
  32. partially greek letters -- the stack had been used for some of the date
  33. stamp instead of the data segment (that sort of stuff makes me really
  34. nervous).   
  35.  
  36. Of course, you can simply ignore all of the C runtime routines -- in a TSR
  37. you may have to anyway because of re-entrency (sp?) problems, but if you
  38. have to give up the runtime stuff you might as well use assembler anyway. 
  39. (Spoken like a true ASM hacker).  
  40.  
  41. Finally, even after you swap stacks, you will (as I did) run into a real
  42. pain -- stack overflow messages that are generated because of the stack
  43. swapping and not by any real stack overflows.  My response to this was to
  44. turn off all stack checking (compile with -Ox, equivalent to living
  45. dangerously).  BUT SURPRISE, runtime library routines check the stack
  46. anyway and kick you out.
  47.  
  48. At this point, I called MS and (HUZZAHS ON ------
  49.  
  50. =============================================================
  51.         MICROSOFT PRODUCT SUPPORT ANSWERED MY QUESTION!!!
  52. =============================================================
  53.  
  54. HUZZAHS OFF -- its the first time they've really answered a question
  55. successfully and I am grateful).  They referred my to the assembler stack
  56. checking routine (which I'd forgotten was supplied on the UTILITIES disk),
  57. which allows me to turn optimization back off, and get around the error
  58. checks.  
  59.  
  60.  
  61. Here are the two routines for stack swapping -- These assume large model
  62. compiles and provide a stack that is accessible only to the assembler
  63. routine.  The stack size is provided by the user.  Call StackADJ() to swap
  64. stacks, and StackRES() to restore original stack.  I call these from within
  65. my C interrupt handler routine (which has already changed DS to the
  66. "correct" value).
  67.  
  68. Redirect any flames about these routines to /dev/null.
  69.  
  70. James H. King
  71. AT&T Bell Laboratories
  72. HO 3K302
  73. homxc!jaynec
  74. 201 949 8908
  75.  
  76. ;    Static Name Aliases
  77. ;
  78. ;    extrn    _CurrentSS:word
  79. ;    extrn    _CurrentSP:word
  80.     extrn    STKHQQ:word         ; stack bottom
  81.  
  82. STACK_TEXT    SEGMENT  WORD PUBLIC 'CODE'
  83. STACK_TEXT    ENDS
  84.  
  85. _DATA    SEGMENT  WORD PUBLIC 'DATA'
  86. LocalStack    db     4024d dup ("stack   ")
  87. StackTop    db    0
  88. Orig_SS        dw    0
  89. Orig_SP        dw    0
  90. Orig_BP        dw    0
  91. Orig_DI        dw    0
  92. Orig_SI        dw    0
  93. OrigSTKHQQ    dw    0
  94. _DATA    ENDS
  95.  
  96. CONST    SEGMENT  WORD PUBLIC 'CONST'
  97. CONST    ENDS
  98. _BSS    SEGMENT  WORD PUBLIC 'BSS'
  99. _BSS    ENDS
  100. DGROUP    GROUP    CONST, _BSS, _DATA
  101.     ASSUME  CS: STACK_TEXT, DS: DGROUP, SS: DGROUP
  102. STACK_TEXT      SEGMENT
  103.  
  104.     ASSUME    CS: STACK_TEXT
  105.     PUBLIC    _StackADJ
  106.     PUBLIC    _StackRES
  107.  
  108. _StackADJ    PROC FAR
  109.     mov    ax,ss
  110.     mov    Orig_SS,ax
  111.     mov    ax,sp
  112.     mov    Orig_SP,ax
  113.     mov    ax,bp
  114.     mov    Orig_BP,ax
  115.     mov    ax,di
  116.     mov    Orig_DI,ax
  117.     mov    ax,si
  118.     mov    Orig_SI,ax
  119.     mov    bp,sp
  120.     mov    ax,STKHQQ
  121.     mov    OrigSTKHQQ,ax
  122.     mov    cx,ss:[bp]        ;load return address offset
  123.     mov    dx,ss:[bp+2]        ;load return address segment
  124.     mov    ax,ds
  125.     mov    ss,ax
  126.     mov    ax,offset LocalStack+4024d    ;load top of local stack
  127.     mov    sp,ax                ;reset stack pointer
  128.     mov    ax,offset LocalStack
  129.     mov    [STKHQQ],ax
  130.     push    dx            ;push return segment to new stack
  131.     push    cx            ;push return offset to new stack
  132.     mov    bp,sp
  133.     ret
  134. _StackADJ    ENDP
  135.  
  136. _StackRES    PROC FAR
  137.     mov    bp,sp
  138.     mov    cx,ss:[bp]        ;load return address offset
  139.     mov    dx,ss:[bp+2]        ;load return address segment
  140.     mov    ax,Orig_SS
  141.     mov    ss,ax
  142.     mov    ax,Orig_SP
  143.     mov    sp,ax
  144.     mov    ax,Orig_BP
  145.     mov    bp,ax
  146.     mov    ax,Orig_SI
  147.     mov    si,ax
  148.     mov    ax,Orig_DI
  149.     mov    di,ax
  150.     mov    ax,OrigSTKHQQ
  151.     mov    STKHQQ,ax
  152.     push    dx            ;push return segment to new stack
  153.     push    cx            ;push return offset to new stack
  154.     ret
  155. _StackRES    ENDP
  156.  
  157. STACK_TEXT    ENDS
  158. END
  159.  
  160.  
  161.