home *** CD-ROM | disk | FTP | other *** search
- {
- The program StackUse below measures your EXACT stack usage
- (REAL mode only). Make sure the constant Ssize is equal to the
- actual physical stack size as defined with the $M directive or
- in the Turbo Pascal IDE settings (the Options/MemorySizes menu).
-
- For your own programs, you just need to call Initstack at the very
- start, then call StackReport whenever you want - or calculate for
- yourself, (Ssize-(VirginStack-StackLimit)) equals the number of
- stack bytes actually used.
-
- Sptr gives you the current stack pointer, and StackLimit is
- a TP system variable (WORD) that contains the current bottom of
- of the stack. StackLimit is usually zero, but some 'sneaky'
- programs raise it so they can hide something there - for example,
- c1;0compiling your program using the replacement run-time libraries
- by Norbert Juffa can raise the StackLimit to 512.
- The stack is filled from top to bottom, so a stack overflow
- means Sptr <= StackLimit.
- UseStack is just an example of a procedure that makes heavy
- use of the stack.
-
- This code can be freely included in any FAQ,
- SNIPPETS, SWAG or what-have-you.
-
- Erik de Neve
- Internet: 100121.1070@compuserve.com
-
- Last update: March 8, 1994
-
- { -*- CUT HERE -*- }
-
- Program StackUse;
-
- {$M 16384,0,0 }
-
- CONST
- Ssize = 16384; {should match stack size as set by the $M directive }
-
- Procedure Initstack; { fills unused stack with marker value }
- Assembler;
- ASM
- PUSH SS { SS = the stack segment }
- POP ES
- MOV DI,StackLimit
- MOV CX,SP { SP = stack pointer register }
- SUB CX,DI
- MOV AL,77 { arbitrary marker value }
- CLD
- REP STOSB
- END;
-
- Function VirginStack:word; { finds highest unused byte on stack }
- Assembler;
- ASM
- PUSH SS
- POP ES
- MOV DI,StackLimit { is usually 0 }
- MOV CX,SP
- SUB CX,DI
- MOV AL,77 { marker value, must be the same as in InitStack }
- CLD
- REPE SCASB { scan empty stack }
- DEC DI { adjust for last non-matching byte in the scan }
- MOV AX,DI
- END;
-
-
- Procedure StackReport; { Reports all sizes in bytes and percentages }
- begin
- WriteLn('Stack Bottom : ',StackLimit:6);
- WriteLn('Current SP : ',Sptr:6);
- WriteLn('Total Stack : ',Ssize:6,
- ' bytes = 100.00 %');
- WriteLn(' Now used : ',Ssize-(Sptr-StackLimit):6,
- ' bytes = ',(Ssize-(Sptr-StackLimit))/Ssize *100:6:2,' %');
- WriteLn(' Ever used : ',Ssize-(VirginStack-StackLimit):6,
- ' bytes = ',(Ssize-(VirginStack-StackLimit))/Ssize *100:6:2,' %');
- WriteLn('Never used : ',(VirginStack-StackLimit):6,
- ' bytes = ',(VirginStack-StackLimit)/Ssize *100:6:2,' %');
- end;
-
-
- Procedure UseStack(CNT:WORD); Assembler; { example stack usage }
- ASM
- MOV AX,0 {dummy value}
- MOV CX,CNT
- @pushit: {perform CNT PUSHes}
- PUSH AX
- LOOP @pushit
- MOV CX,CNT
- @poppit: {perform CNT POPs}
- POP AX
- LOOP @poppit
- END;
-
-
- BEGIN
- InitStack; { prepare stack }
- UseStack(1000); { perform a number of PUSHes and POPs }
- StackReport; { report stack usage }
- END.