ID Number: Q58194
4.00 5.00 5.10 | 5.10
MS-DOS | OS/2
Summary:
The following information describes how to rewrite the stack checking
routine (__chkstk) for C versions 5.10 and earlier. This process is
necessary if you want to work around some of the assumptions that
__chkstk makes. For instance, you might want to change the fact that
DS is assumed to equal SS (DS==SS) or that Microsoft's internal
variables point to the beginning and end of the stack.
More Information:
The sample code below demonstrates what is necessary for writing your
own __chkstk routine.
The stack checking routine actually allocates space on the stack, so
writing a stack checking routine that just does a RET will not work,
it must modify the stack. For example, a function may assume that it
has X amount of stack space and if the stack space hasn't been
allocated, the function will write over whatever is currently on the
stack (this function could do a memory move of data onto the stack
rather than pushing and popping the stack). Because of this, you must
allocate space on the stack.
You cannot simply turn off stack checking because some functions
[printf() in particular] have a call to _chkstk() hardcoded.
To get the sample code working, let's assume that it is in a file
called CHKSTK.ASM. Assemble with the /MX switch, to make all symbols
case sensitive, as follows:
MASM /MX chkstk.asm ;
or
QCL /Cx chkstk.asm
You can then link your program with this module in the following way:
LINK /NOE program chkstk ;
This assumes that your program has been compiled successfully and that
it is named "program." It also assumes that you are using the same
memory model for both modules.
This information is correct for Microsoft C versions 5.10 and earlier.
It is also correct for QuickC versions 2.00 and earlier, as well as
QuickAssembler version 2.01.
Sample Code
-----------
; a chkstk routine for the small/compact memory models
.MODEL SMALL
.DATA
PUBLIC STKHQQ
STKHQQ dw dataoffset _end+STACKSLOP
.CODE
PUBLIC __chkstk
__chkstk PROC
pop cx ; grab the return address
sub sp, ax
jmp cx
__chkstk ENDP
END
; a chkstk routine for the medium/large memory models
.MODEL LARGE
.DATA
PUBLIC STKHQQ
STKHQQ dw dataoffset _end+STACKSLOP
.CODE
PUBLIC __chkstk
__chkstk PROC
pop cx ; grab the return address
pop dx ; (and its segment)
sub sp, ax
push dx ; push the return address
push cx
ret ; and go back to that address
__chkstk ENDP
END
Note: STACKSLOP is defined as being 256 bytes for DOS and 512 bytes
for OS/2, although this may change with future versions of the
compiler.