Hi,
I would like to read the current value of the stack pointer from within my C-code. Is this possible?
I can't find the SP register in the S12X manual.
Regards
J
foo()
{
short stkptr;
asm{ STS stkptr }
}
If you want to check if SP isn't lower than some critical threshold, then just take address of function scope auto variable (on stack) and compare it.
foo()
{
void *stk;
stk = &stk;
if(stk < (void*)0x2000)
{
...
}
}
Isn't there a risk that the optimizer will put "stk" into an index register? I'm not quite sure what would happen in that case, but I guess that you'd get the current content of the index register in return, ie rubbish.
I'd declare that pointer as volatile just to be on the safe side.
Also, I don't think C allows the cast from void** to void*. I would do like this instead:
foo()
{
volatile uint16_t stack;
stack = (uint16_t) &stack;
if(stack < 0x2000)
...
To be even more sure one can use a uint32_t as that will never fit into the D acc of the S12, and thereby can't be optimized.
Unlike register variables, auto variables have the address. I don't think compiler has the right to replace real address of variable with something meaningless. I don't mind allocating auto variables in registers, I don't mind if stk isn't allocated on stack, but compare expression has to compare something meaningful, not random data because of too smart optimization.
Even with volatile, it is still rubbish, because C doesn't require stack at all. Compiler can allocate stk not in the stack space, like it is done in C compilers for PIC (PIC16, PIC18).
uint32_t doesn't help, because there are at least 3 16bits CPU registers, more than enough for uint32_t. Also optimizer may be too smart and ignore not used high order bits.
Out of curiousity I disassembled the two examples. Both translate into the same code,
; with void*
LEAX 2,-SP
STX 0,SP
CPX #8192
; with integer
LEAX 2,-SP
STX 0,SP
LDX 0,SP
CPX #8192
After a bit of research I also found out that the pointer cast is valid, just because it is a void pointer. Though to be picky, stk < (void*)0x2000) is undefined behavior in the C language, as the pointers don't point at the same aggregate.
Thanks!