这是我最终用于带有 XC16 编译器的 dsPIC33EP512MU810 的代码。通过创建一个自动变量,我可以访问堆栈顶部附近,然后增加几个字节 ( STACK_VAR_PAD
),并用保护字节填充堆栈的其余部分。
#define STACK_VAR_PAD 0x0020
#define TOP_OF_STACK_ADDR 0x4000
#define STACK_GUARD_BYTE 0xEE
void WriteStackGuardBytes(void)
{
static __eds__ char * ptr;
static unsigned int start_addr;
static unsigned int addr;
//Use a variable on the stack
char stack_var;
ptr = &stack_var;
//Casting to 32-bit first supresses complier warning
//This chip uses a 16-bit address space
start_addr = (unsigned long int)ptr + STACK_VAR_PAD;
for (addr = start_addr; addr < TOP_OF_STACK_ADDR; addr++)
{
*((unsigned int *)(addr)) = STACK_GUARD_BYTE;
}
}
unsigned int ReadStackGuardBytes(void)
{
static __eds__ char * ptr;
static unsigned int start_addr;
static unsigned int addr;
static unsigned int top_addr;
//Use a variable on the stack here
char stack_var;
ptr = &stack_var;
//Casting to 32-bit first supresses complier warning
//This chip uses a 16-bit address space
start_addr = (unsigned long int)ptr;
top_addr = start_addr;
for (addr = start_addr; addr < TOP_OF_STACK_ADDR; addr++)
{
if (*((unsigned int *)(addr)) != STACK_GUARD_BYTE)
{
top_addr = addr;
}
}
return TOP_OF_STACK_ADDR - top_addr;
}
链接器声称堆栈停止在0x8000
(我设置设置以生成映射文件),但我看到零0x4000
,然后垃圾数据过去。我完全理解堆栈的内容是未确定的,但我也用这种方法确定我的堆栈永远不会超过这个0x1500
左右,因此只检查0x4000
对我有用。