home *** CD-ROM | disk | FTP | other *** search
- In article <539@siemens.UUCP>, jrv@siemens.UUCP (James R Vallino) writes:
- > In article <2045@optilink.UUCP> elliott@optilink.UUCP (Paul Elliott x225) writes:
- > >I am doing some TSR stuff using Microsoft C 5.0, and would like to
- > >get access to the SS and SP registers (to set up a local stack).
- > >TurboC has psuedo-variables for all the registers, and it is pretty
- > >simple to read and write to these and do what I want (in TutboC).
- >
- > I had the same wish and could not find a way to set up a local stack short
- > of some assembly code. I punted and took the risk of using whatever stack
- > is active when the TSR is entered. So far that has worked but I would be
- > wary of not putting in the stack swap for a general use TSR.
- >
-
- That's a bad risk in my experience.
-
- I have successfully managed stack swapping -- you are right, assembler is
- the only way. At the end of this I will include the source code, NO
- GUARENTEES -- this works for me, but it's by no means foolproof.
-
- You'd better swap stacks or you might get in real deep stuff. You should
- realize that if you don't swap stacks, you should compile so that the code
- knows that DS<>SS when its compiling your routine. This is accomplished
- with a -Aw (FLAME ON: WHY DOES MICROSOFT INSIST ON CASE SENSITIVE COMMAND
- LINE OPTIONS. FLAME OFF -- I feel better ), as in "cl -Od -AL -Aw foo.c".
- Without this, I had several bizarre problems like code hanging on the
- statement "x = y".
-
- Even with this option, however, you must realize that almost all of the C
- runtime libraries are compiled to work only if DS=SS (I had originally
- written iff but MS bugs made me change the wording), and you can't really
- be sure whether or not the routine you want will cause a bizarre hangup.
- For example, ctime() uses the stack partially -- in my example, I simply
- printed the current time, and it came out as partially correct, and
- partially greek letters -- the stack had been used for some of the date
- stamp instead of the data segment (that sort of stuff makes me really
- nervous).
-
- Of course, you can simply ignore all of the C runtime routines -- in a TSR
- you may have to anyway because of re-entrency (sp?) problems, but if you
- have to give up the runtime stuff you might as well use assembler anyway.
- (Spoken like a true ASM hacker).
-
- Finally, even after you swap stacks, you will (as I did) run into a real
- pain -- stack overflow messages that are generated because of the stack
- swapping and not by any real stack overflows. My response to this was to
- turn off all stack checking (compile with -Ox, equivalent to living
- dangerously). BUT SURPRISE, runtime library routines check the stack
- anyway and kick you out.
-
- At this point, I called MS and (HUZZAHS ON ------
-
- =============================================================
- MICROSOFT PRODUCT SUPPORT ANSWERED MY QUESTION!!!
- =============================================================
-
- HUZZAHS OFF -- its the first time they've really answered a question
- successfully and I am grateful). They referred my to the assembler stack
- checking routine (which I'd forgotten was supplied on the UTILITIES disk),
- which allows me to turn optimization back off, and get around the error
- checks.
-
-
- Here are the two routines for stack swapping -- These assume large model
- compiles and provide a stack that is accessible only to the assembler
- routine. The stack size is provided by the user. Call StackADJ() to swap
- stacks, and StackRES() to restore original stack. I call these from within
- my C interrupt handler routine (which has already changed DS to the
- "correct" value).
-
- Redirect any flames about these routines to /dev/null.
-
- James H. King
- AT&T Bell Laboratories
- HO 3K302
- homxc!jaynec
- 201 949 8908
-
- ; Static Name Aliases
- ;
- ; extrn _CurrentSS:word
- ; extrn _CurrentSP:word
- extrn STKHQQ:word ; stack bottom
-
- STACK_TEXT SEGMENT WORD PUBLIC 'CODE'
- STACK_TEXT ENDS
-
- _DATA SEGMENT WORD PUBLIC 'DATA'
- LocalStack db 4024d dup ("stack ")
- StackTop db 0
- Orig_SS dw 0
- Orig_SP dw 0
- Orig_BP dw 0
- Orig_DI dw 0
- Orig_SI dw 0
- OrigSTKHQQ dw 0
- _DATA ENDS
-
- CONST SEGMENT WORD PUBLIC 'CONST'
- CONST ENDS
- _BSS SEGMENT WORD PUBLIC 'BSS'
- _BSS ENDS
- DGROUP GROUP CONST, _BSS, _DATA
- ASSUME CS: STACK_TEXT, DS: DGROUP, SS: DGROUP
- STACK_TEXT SEGMENT
-
- ASSUME CS: STACK_TEXT
- PUBLIC _StackADJ
- PUBLIC _StackRES
-
- _StackADJ PROC FAR
- mov ax,ss
- mov Orig_SS,ax
- mov ax,sp
- mov Orig_SP,ax
- mov ax,bp
- mov Orig_BP,ax
- mov ax,di
- mov Orig_DI,ax
- mov ax,si
- mov Orig_SI,ax
- mov bp,sp
- mov ax,STKHQQ
- mov OrigSTKHQQ,ax
- mov cx,ss:[bp] ;load return address offset
- mov dx,ss:[bp+2] ;load return address segment
- mov ax,ds
- mov ss,ax
- mov ax,offset LocalStack+4024d ;load top of local stack
- mov sp,ax ;reset stack pointer
- mov ax,offset LocalStack
- mov [STKHQQ],ax
- push dx ;push return segment to new stack
- push cx ;push return offset to new stack
- mov bp,sp
- ret
- _StackADJ ENDP
-
- _StackRES PROC FAR
- mov bp,sp
- mov cx,ss:[bp] ;load return address offset
- mov dx,ss:[bp+2] ;load return address segment
- mov ax,Orig_SS
- mov ss,ax
- mov ax,Orig_SP
- mov sp,ax
- mov ax,Orig_BP
- mov bp,ax
- mov ax,Orig_SI
- mov si,ax
- mov ax,Orig_DI
- mov di,ax
- mov ax,OrigSTKHQQ
- mov STKHQQ,ax
- push dx ;push return segment to new stack
- push cx ;push return offset to new stack
- ret
- _StackRES ENDP
-
- STACK_TEXT ENDS
- END
-
-