Hi all,
How do I read the stack pointer address in a C language code? I am using the MC9S08LC60 MCU.
I wanted to have some control of my stack pointer where-abouts. I'm afraid it will overflow when I least expect it, specially since I have only estimated it, but am not sure at all how close to overflowing I actually am.
I have a timer interrupt, and I believe that's the most critical point, since it may be triggered when the main thread is in it's most nested condition (where stack is at it's lowest), so if I can detect the lowest stack value in that condition, I'll have a good estimate if my stack is well dimentioned.
If you have other stack control ideas, I'll be happy to hear them.
Thank you
Solved! Go to Solution.
The easiest and cleanest way is to use inline assembler: then you can read the SP right away. In pure C language you would have to use some sort of dirty hack like this:
interrupt void isr (void)
{
volatile uint32 debug_sp = 0; /* volatile so that it wont be optimized away, uint32 so that it is guaranteed to end up on the stack and not in an accumulator. */
if( (uint16)&debug_sp - STACK_START > some_size)
{
do_something();
}
}
Another trick is to download the program with the BDM, then in the debugger set the whole stack area to some unlikely value like 0xAA. Let the program run for a while, halt it and check the stack, to see at which address 0xAA still exists without having been overwritten. If there is no 0xAA anywhere, the stack has overflowed.
Not at all. Timer interrupt is often synchronized with main routine. If for example main thread is not executing most nested routines until timer interrupt signals something, then your most critical point can be synchronized and happen always somewhere between two adjacent timer interrupt events.
You could clear stack space or initialize it with some constant before enabling interrupts and jumping to main(). Then you could periodically scan stack space upwards from the bottom to find first occurence of modified byte. Or, better, to make checks faster, just check if safe minimum of N bytes was not modified.
The easiest and cleanest way is to use inline assembler: then you can read the SP right away. In pure C language you would have to use some sort of dirty hack like this:
interrupt void isr (void)
{
volatile uint32 debug_sp = 0; /* volatile so that it wont be optimized away, uint32 so that it is guaranteed to end up on the stack and not in an accumulator. */
if( (uint16)&debug_sp - STACK_START > some_size)
{
do_something();
}
}
Another trick is to download the program with the BDM, then in the debugger set the whole stack area to some unlikely value like 0xAA. Let the program run for a while, halt it and check the stack, to see at which address 0xAA still exists without having been overwritten. If there is no 0xAA anywhere, the stack has overflowed.
Hi, it's been a year since this thread was active, but maybe you are still "around"...
Inline assembler for reading the SP to a c-variable; what would this look like. Totally inexperienced in assembler coding...
Hello, and welcome to the forum.
Maybe the following for HCS08 -
unsigned int readSP( void){ unsigned int temp; __asm tsx; // Transfer stack pointer+1 to H:X __asm aix #-1; __asm sthx temp; return temp;}
Regards,
Mac
Thanks! Exactly what I was looking for!
Hello,
Perhaps I should clarify one aspect, which I had previously over-looked.
Since the previous code snippet described a separate function, in which a 16-bit local variable was also defined, the stack pointer address returned by the function will be that within the function. However, if you require the stack pointer address present just prior to the function call, the adjustment should be __asm aix #3, rather than __asm aix #-1, to allow for both the local variable and the return address.
Regards,
Mac
Lundin, Kef
Filling the RAM with 0xAA in BDM worked beautifully! I can now see clearly how deep the stack goes!
Thank you both for your answers!