未经许可,不得转载!(:з)∠)
参考:
STM32 大小端序 与 堆栈及其增长方向分析
函数调用的压栈出栈过程
一个子程序返回时出现了HardFault_Handler,
我在子函数的最后的部分以及子函数返回后的地方都增加了调试语句,
我能收到子函数的调试信息,
但是无法收到子函数返回后的调试信息,
这说明,子函数在返回时出现了错误
苦思冥想,被群中一大佬一语惊醒:
“进这个中断的,基本90%都是指针问题”
回想一下,在这个函数中我使用了大量的字符串的操作,而这些字符串操作中经常使用到一个用作暂存字符串的数组temp,这家伙只有64字节的大小,怎么想怎么可疑,将其增加到128字节后,问题得以解决。
......
......
......
Subroutine("你是猪变的吧!");
printf("我执行到这儿了 !\r\n");
......
......
......
void Subroutine(u8* srt)
{
u8 temp[64];
getSeparatorLeft(temp, srt, ',');//取分隔符左边
......
......
......
if(!strcmp("xxxxxx",(char*)temp))
{
......
......
......
}
printf("我执行完了鸭 !\r\n");
}
那么我们来分析一下,为什么数组越界了,在当时不报错,而在函数返回时才报错呢?
让我们来康康:
首先,STM32的栈,是向下生长的
其次,数组是向上生长的
好,事情到这里就很清楚了
在进入子函数之前,会进行压栈,会保存函数的返回地址以及一些局部变量,
然后在栈顶新建子函数的栈
地址 | 内容 |
---|---|
0X2000 0010 | 返回地址 |
0X2000 0014 | 临时变量 |
… | … |
0X2000 0061 | 数组temp[]的第二个元素 |
0X2000 0060 | 数组temp[]的第一个元素 |
当我们的程序使用temp来暂存字符串的时候,而字符串的长度太长,把返回地址“冲”了的话,
当子函数返回时,自然是会出错了。
以上。