Writing Your Own C 5.00/5.10 or QuickC 2.00 __chkstk Routine

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.