www.digitalmars.com         C & C++   DMDScript  

c++ - sc -s loops forever for 16-bit code

reply Larry Brasfield <larry_brasfield snotmail.com> writes:
When I use the -s compiler option to insert
stack checking code, the generated code is
incorrect.  It performs an IN instruction
and cycles SP in an endless loop.

This bug is exhibited by the release compiler
(scppn.exe) dated 5/22/2002 whose banner reads
  Digital Mars Compiler Version 8.28n
and by the beta compiler having size 759,836
and dated 6/19/2002  19:07 whose banner reads
  Digital Mars Compiler Version 8.28n

With a source having a main() compiled thusly:
  sc -c -cpp -o -g -4 -DSTACK_CHECK -cod -s -mm coprand.cpp
and disassembled with object obtained via:
  obj2asm -x -o coprand.obj >coprand.asm
I get the following results:

coprand.asm reads (partially):
...
;int
;main(int an, char *ap[])
;{
_main:
01c0:   55              push    BP
01c1:   8B EC           mov     BP,SP
01c3:   31 D2           xor     DX,DX
01c5:   81 EC 00 10     sub     SP,01000h
01c9:   85 24           test    [SI],SP
01cb:   4A              dec     DX
01cc:   75 F4           jne     $+FFFFFFF5h

coprand.cod reads (over same region):
;int
;main(int an, char *ap[])
;{
_main:
                push    BP
                mov     BP,SP
                xor     DX,DX
                sub     SP,01000h
                test    [SI],SP
                dec     DX
                jne     L1C2

Note that L1C2 does not exist, but should be
on the middle of the mov  BP,SP instruction
according to usual label generation logic.

Here is CodeView's rendering of the same
entry code for a main() compiled with -s :

116:  {
09F8:01C0 55             PUSH      BP
09F8:01C1 8BEC           MOV       BP,SP
09F8:01C3 31D2           XOR       DX,DX
09F8:01C5 81EC0010       SUB       SP,1000
09F8:01C9 8524           TEST      WORD PTR [SI],SP
09F8:01CB 4A             DEC       DX
09F8:01CC 75F4           JNZ       main+0002 (01C2)

This is what CodeView says after the JNZ
is first taken (and it disassembles the
last half of the MOV BP,SP instruction):

09F8:01C2 EC             IN        AL,DX
09F8:01C3 31D2           XOR       DX,DX
09F8:01C5 81EC0010       SUB       SP,1000
09F8:01C9 8524           TEST      WORD PTR [SI],SP
09F8:01CB 4A             DEC       DX
09F8:01CC 75F4           JNZ       main+0002 (01C2)

The loop never ends since DX is reset to 0
on each pass.

Just in case it matters, here is the source
excerpt that produces the above, although
it occurs for any function compiled with -s.

int
main(int an, char *ap[])
{
	tCopForkParm doparm;

	cprintf("Hit a space.\r\n");
	while (!kbhit()) {
	  sleep(1);
	}
...

This problem appears to occur only for
16-bit compilations.  The code seems to
be intended to avoid the growing stack 
page fault problem when frame size is
greater than the 4K page size.  This
probing-by-4K-increments is not at all
necessary in the DOS environment, so I
imagine this can be easily fixed.

The ctgCompilingCode.html help says:
  Use the -s compiler option (see below) to
  generate stack-overflow checking code on
  entry to every function, although this
  increases program size and reduces speed.
  Use stack-overflow checking if you suspect
  stack-overflow errors (a symptom is a
  mysterious crash). 

The SC.exe no-arguments help says:
     -s  stack overflow checking

I see no evidence of stack overflow checking
in the generated code for either 16-bit or
32-bit compilations.  The -s option appears
to always create probing-by-4K-increments 
code rather than calls to chkstk.

-- 
-Larry Brasfield
(address munged, s/sn/h/ to reply)
Jun 29 2002
parent "Walter" <walter digitalmars.com> writes:
You're right, it is a bug. I shall get it fixed. (Thanks for the great bug
report!) -Walter
Jul 01 2002