Category : C++ Source Code
Archive   : C_ALL.ZIP
Filename : TI643.ASC

 
Output of file : TI643.ASC contained in archive : C_ALL.ZIP







PRODUCT : Borland C++ NUMBER : 643
VERSION : All
OS : PC DOS
DATE : August 20, 1992 PAGE : 1/4

TITLE : Using a Dynamically Allocated Stack in C





/*[]------------------------------------------------------------[]*/
/*| |*/
/*| 'Using a LARGE temporary stack in a small program' |*/
/*| |*/
/*| |*/
/*| Copyright (c) 1991 by Borland International |*/
/*| All Rights Reserved. |*/
/*| |*/
/*[]------------------------------------------------------------[]*/

/************************************************************************
NOTE: If you want to use the stack-checking code in Turbo C++ or
Borland C++ then you must be in the LARGE or HUGE memory model.
**********************************************************************/

/*
The theory here is the stack checking option generates the
following code at the beginning of every function that was compiled
with it on:

_function proc far
push bp
mov bp, sp
cmp word ptr DGROUP:_stklen, sp
ja short @1@74
call far ptr F_OVERFLOW@
@1@74:
. ; the rest of the function...
.
.


This is basically checking SP against the stack length and if SP ever
becomes greater than _stklen, (which can only happen if you use all
the stack space and then wrap SP from seg:0000 to seg:FFFE) then the
overflow function gets called.

All we are doing is allocating a 66K buffer from farmalloc,
normalizing the pointer to get a full segment, saving the old values
for ss, sp, and _stklen, setting the new values, and calling the
stack-hungry function.














PRODUCT : Borland C++ NUMBER : 643
VERSION : All
OS : PC DOS
DATE : August 20, 1992 PAGE : 2/4

TITLE : Using a Dynamically Allocated Stack in C




This can be very useful for qsort() programs that wish to sort
very large tables, and don't need 64k of stack all the time.

If you don't use stack checking then you can use this trick from any
model.
*/


#if !defined (__LARGE__)
#error Must be in the LARGE model!
#endif


#include
#include
#include
#include
#include

unsigned _stklen = 2048; // stack = 2k

unsigned int goober = 0;
char *p;

void recurse1 (void)
{
goober++;
cprintf ("\rCalling recurse1() %u ", goober);
recurse1 ();
}

void do_reg (void)
{
recurse1 ();
}

void do_alloc (void)
{
// NOTE: these all MUST be static (or global) because if they were local
// the compiler wouldn't be able to access them after we switch
// our stacks.

static char far *p;













PRODUCT : Borland C++ NUMBER : 643
VERSION : All
OS : PC DOS
DATE : August 20, 1992 PAGE : 3/4

TITLE : Using a Dynamically Allocated Stack in C




static unsigned old_ss, old_sp, old_stklen;

if ((p = farmalloc (66000L)) == NULL)
{
printf ("\nNo room to allocate stack buffer!\n");
exit (1);
}
/*
We now have a pointer xxxx:0004. This example will overwrite the
bottom and top of the segment. To prevent serious memory
corruption, we must allocate a full 64K segment and normalize it
ourselves. Now if we corrupt memory at xxxx:0000 or xxxx:FFFF we are
still within the buffer we allocated, and thus are safe. This
saves us from incurring the overhead of having a HUGE pointer for
the address of our buffer.
*/

(long)p += 0x00010000; // increment segment
p -= 4; // set offset to zero

// p is now = (xxxx + 1):0000

old_ss = _SS; // save old values
old_sp = _SP;
old_stklen = _stklen;

_stklen = 60000U; // change the stack length (for checking)

_SS = FP_SEG (p); // set up our new stack segment

_SP = FP_OFF (&(p[_stklen])); // set the stack to the top

goober = 0; // reset our counter
recurse1(); // call the recursive DEATH function

// If we were to get to this point...

_SS = old_ss; // reset the values
_SP = old_sp;
_stklen = old_stklen;

(long)p -= (0x00010000 - 4);
// set the pointer back to what it was to free it













PRODUCT : Borland C++ NUMBER : 643
VERSION : All
OS : PC DOS
DATE : August 20, 1992 PAGE : 4/4

TITLE : Using a Dynamically Allocated Stack in C




free ((void *) p);
}

int main (void)
{
cputs ("\n\rBIG Stack Example (c) 1991 by Borland International\r\n");
// do_reg(); // call this function to compare with regular stack
do_alloc (); // call this one to allocate a BIG temporary stack
return 0;
}

DISCLAIMER: You have the right to use this technical information
subject to the terms of the No-Nonsense License Statement that
you received with the Borland product to which this information
pertains.




































  3 Responses to “Category : C++ Source Code
Archive   : C_ALL.ZIP
Filename : TI643.ASC

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/