🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.os.msdos.programmer
Article #2881

Re: Porting UNIX apps. to MS-DOS

#2881
From: Derek R. Foster
Date: Thu, 01 Nov 1990 06:03
101 lines
5761 bytes
In article <1990Oct31.190520.11526@Octopus.COM> stever@octopus.UUCP (Steve Resnick ) writes:
>In article <9449@jarthur.Claremont.EDU> dfoster@jarthur.Claremont.EDU (Derek R. Foster) writes:
>
>[Stuff deleted]
>>
>>Although this is generally true in "nice" programs, there may be a somewhat
>>kludgy workaround for this. DISCLAIMER: I haven't tried the following
>>suggestion. This is all theory on my part, and I would be interested in
>>hearing comments on it. Also the code I present is sketchy at best, and
>>is probably outright wrong in some respects. Don't expect it to work;
>>just use it as a model.
>>
>>Anyway, you might try changing the stack segment pointer to point into
>>a new segment of your own when the old one gets filled. For instance,
>>if you can identify a particular part of the program which will be
>>called only when the stack is almost filled, you might try something
>>like ...
>>
>>void huge char ABuffer[(some fancy calculation probably involving _stklen
>>  to preserve the ability to detect stack overflow) + 16 (the 16 is to
>>  ensure that I can always get a buffer of at least the size I want 
>>  which starts on an even paragraph boundary)];
>>
>Warning Will Robinson! :) There is nothing to prevent you from changing the
>stack on a '86 processor, but you *cannot* access more than 64K. Even
>though TC supports huge pointers and deals with the additional segment
>arithmetic, the processor doesn't. Eg, PUSH/POP instructions will fail
>on a segment wraparound. 

Although this is technically true, the way you
have phrased it is somewhat misleading. The limit is 64k PER STACK
SEGMENT. The technique I am using first fills up the "default"
stack segment, <= 64k, then switches to a new one when that one is
full, also <= 64k, for a resultant "effective" stack size of >64k.
So even though the stack pointer (which, as another poster pointed out,
I forgot to mention in my sample code) can never be farther away from
_SS than 64k, we could build an indefinitely long "linked list" of 
stacks, just as long as we remember to switch from one to the other
when we are in danger of over/underflowing the one we are in. We should
never have to deal with PUSHes and POPs over a segment boundary during
this process, since if the stack pointer gets close to one, we're
supposed to switch to a new stack.

>
>If you do change the stack segment and pointer to a new address you cannot
>do any stack checking since the stack segement is different than the one
>defined by the C runtime startup routines.
>

Not necessarily...

I think it is _highly_ likely that _stklen measures the height of the
stack relative to the stack segment register, and not to some absolute
position in memory. (After all, what would be the point of using
the segment value of a quantity if it's never supposed to change, and
you always have a (normally constant) register pointing at it?)
As such, if each "link" in the "linked list" is of
a size to accomodate _stklen, then if we overflow the current
stack segment by exceeding _stklen, a "stack overflow" message is
printed, but if we instead switch to a new stack and reset the
stack pointer, we can keep adding to the new stack until we are
again in danger of exceeding _stklen relative to the _new_ stack segment.
Thus the stack checking routines perform their intended purpose, sort of,
namely detecting a program trying to write stack data outside of any
stack segment.

>>  oldSS = _SS;
>	
>	You *MUST* disable interrupts during this operation. If an interrupt
>	occures during the stack segment transition, you will not return
>	from the interrupt correctly and crash the machine.

True. Definitely disable interrupts.

Oh, incidentally, another bug in my example code: don't store the
old _SS in an automatic (local) variable. Since this variable actually
resides on the first stack, once you change it, you have no way to
access the old value. Use a static variable instead. In fact, remember
that changing _SS and/or _SP will make a function "forget" ALL its
local variables' values until the old values of _SS and _SP are
restored. Perhaps a better way to do my second example would be to
have a function which has no other purpose than to swap the stacks,
call other functions, then swap the stacks back. The calling
routine would then decide whether to call the other functions directly,
or to make a call through the swapping function. (The decision being made
by determining how much stack space is left in the current segment.) 
This way you wouldn't have to worry about losing the values of
various local variables over the course of a stack swap.

Also, for the same reason, don't even THINK of trying this technique
in a memory model with near pointers. You won't be able to refer to
local variables of previously-called functions by address if you do,
since they may be in a different segment... Bad Things would happen.

>steve.resnick@f105.n143.z1.FIDONET.ORG - or - apple!camphq!105!steve.resnick
>Flames, grammar errors, spelling errrors >/dev/nul
>The Asylum OS/2 BBS - (408)263-8017 IFNA 1:143/105.0

I hope this clarifies things a little. Thanks for the input.

Derek Riippa Foster
Technical Details
Message-ID: <9478@jarthur.Claremont.EDU>
Path: arc1-ca.pugleaf.net!utzoo!utgpu!watserv1!watmath!att!att!pacbell.com!ucsd!usc!elroy.jpl.nasa.gov!jarthur!dfoster
References: <1990Oct26.223541.26634@NCoast.ORG> <9449@jarthur.Claremont.EDU> <1990Oct31.190520.11526@Octopus.COM>

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!utgpu!watserv1!watmath!att!att!pacbell.com!ucsd!usc!elroy.jpl.nasa.gov!jarthur!dfoster
From: dfoster@jarthur.Claremont.EDU (Derek R. Foster)
Newsgroups: comp.os.msdos.programmer
Subject: Re: Porting UNIX apps. to MS-DOS
Message-ID: <9478@jarthur.Claremont.EDU>
Date: 1 Nov 90 06:03:45 GMT
References: <1990Oct26.223541.26634@NCoast.ORG> <9449@jarthur.Claremont.EDU> <1990Oct31.190520.11526@Octopus.COM>
Organization: Harvey Mudd College, Claremont, CA 91711
Lines: 101