You are on page 1of 8

Roman Budek

Industry Consultant
RomanB60156@yahoo.com

rev: 6/6/03
Microcontrollers Application Note #33 orig: 9/13/99
Stack overflow detection

The default selection for the NEC software simulator, emulator, and single chip
device is to not detect stack overflow conditions. However, the NEC software
simulator and emulator can be setup to check for this important condition.

Stack overflow detection is very important, especially if converting between flash


devices and mask devices. The flash device might have more RAM than the
mask device, so a flash device might be fully operational but the mask device will
not function properly.

To adjust the size of the stack, see Microcontroller Application Note #54, which
shows how to minimize RAM and ROM requirements. It also discusses how the
RAM can be allocated to provide more or less stack space.

The first approach is to setup the simulator and emulator to detect stack overflow
conditions.

AN_uc33.doc
Simulator and Emulator

1. Open the configuration menu


Select Option -> Configuration

2. Set the stack size


Select the STACK option under Memory Attribute. Then enter the address range. The
simulator and emulator will now generate a breakpoint if the address range is exceeded.

Page 2 of 8
Detecting in a single chip device

Sometimes it is desirable to check for stack overflow problems directly on a


microcontroller. If an emulator is not present, then the microcontroller should
itself check for stack overflow problems.

However, this stack overflow routine will probably only be used for design
verification, and then will be turned off for the mask device. This section will
describe how this self checking code can be turned on or off, as desired, without
using extra ROM space on the mask device.

Note that if a stack overflow is detected with self checking, that does not mean
that it will necessarily occur in the actual device. For instance, the overhead for
running the function calls is 4 bytes (HL and AX) are pushed onto the stack.
Therefore, if the stack overflow is detected, then use caution to determine the
self check routine is causing the stack overflow.

However, if the self check routine does NOT find problems, then the software
should run fine in the mask device. If the self check routine can handle the 4
extra bytes of overhead (HL and AX) then the software should run fine in the
actual application.

As an example, let us use the uPD78F9468 and uPD789464 devices. The


uPD78F9468 device has more RAM and ROM, and it will be used for
development. The final mask device will be the uPD789464. The memory maps
are shown below:

Page 3 of 8
Page 4 of 8
Page 5 of 8
COMMENTS
ACTUAL CODE
#pragma sfr
#pragma asm

#pragma EI
#pragma rot
#pragma STOP
#pragma nop

//Determines whether a stack overflow check will be done


#define CheckStack 0 //=1, go ahead and check <-- Compiler
//=0, mask device so skip the test constant
will either
include or
remove stack
routines

//If stack overflow then keep code otherwise not!


#if CheckStack <-- If stack
check is
void SetStkOvrFlw() //Check stack overflow enabled then
{ this routine
/* will be
This routine will setup the stack overflow. The compiled.
goal is to set the 3 addresses after STEND (stack If not, then
end) to 0FFh. You need to check all 3 addresses ROM is not
because some calls are 3 bytes. The micro would used
never return back to 0FFh, so that is an invalid
address. If these memory locations contain anything
other than 0FFh, then the stack overflowed.

*/

#asm <-- Routine is


push hl in assembler
push ax

mov a,#0FFh; Would never be a valid address <-- Look at


movw hl,#0FDFDh; Start of stack overflow area memory map
mov [hl],a; 0FDFDh address and start
this 3 bytes
incw hl before STEND
mov [hl],a; 0FDFEh address

incw hl
mov [hl],a; 0FDFFh address

pop ax
pop hl

#endasm

#endif

Page 6 of 8
//If stack overflow then keep code otherwise not!
#if CheckStack <-- If stack
check is
void CheckStkOvrFlw() //Check stack overflow enabled then
{ this routine
#asm will be
push hl compiled.
push ax If not, then
ROM is not
movw hl,#0FDFDh; Stack should NOT be here used
mov a,[hl]; First address
cmp a,#0FFh;
bz $?LChk2nd; Everything okay so continue <-- Tags in ASM
br $?LStkErr; Oops, there was an error <-- code which
is embedded
?LChk2nd: in C must
incw hl start with
mov a,[hl]; Second address ?L
cmp a,#0FFh;
bz $?LChk3rd; Everything okay so continue
br $?LStkErr; Oops, there was an error

?LChk3rd:
incw hl
mov a,[hl]; Third address
cmp a,#0FFh;
bz $?LFinChk; Everything okay so done

?LStkErr: <-- If stack


mov a,#00h; Turn LED on by grounding port pin overflow
movw hl,#0FF00h; Address of port 0 SFR then stop
mov [hl],a; Turn LED on micro and
stop; Shut down the device light LED on
br $?LStkErr; Keep looping Port 0

?LFinChk:
pop ax
pop hl

#endasm

#endif

void main()
{
unsigned int temp;
unsigned int cnt;
unsigned int ExitFlag;

PCC = 0x00; //Max CPU speed


SCKM = 0x00; //Enable sub clock oscillator

Page 7 of 8
//If stack overflow then keep code otherwise not!
#if CheckStack <-- If check is
SetStkOvrFlw(); off, then do
#endif not call
this
EI(); //Enable all interrupts routine.

while(1)
{ <-- Main loop

//Check the stack if the option is set


#if CheckStack <-- Check stack
CheckStkOvrFlw(); condition
#endif when
convenient,
} every so
often.
}

Please feel free to call me if there are any questions.

Roman Budek

Page 8 of 8

You might also like