1, 函数局部变量栈地址是运行时才分配的,函数调用返回后分配的站空间被回收重复利用
2, 程序中所有函数共用一段栈空间,可以把它称为线程栈空间——线程栈起始地址及栈大小,被调的函数运行过程不断在这段栈空间进行进栈出栈,某段地址可能会被重复使用多次。
3, 局部变量数组访问越界并不一定会导致段错误,越界访问肯定产生内存栈区内容覆盖,覆盖的是关键数据时会导致异常,比如函数返回地址被覆盖,此时pc指针指向了未知区域而导致段错误。
4, 函数栈分配原则先给本函数分配栈区,运行到调用的子函数时再给子函数分配栈区,栈区分配起始地址紧接上次分配的最后地址。
5, 如果函数中有条件语句,例如:
If(ret == 0)
{
S8 a[100] = {0};
}
Else
{
S8 b[200] = {0};
}
则会给此函数分配条件语句中占空间最大的一段区间,即分配200个字节,如果ret是0,则a会占用200个字节栈区空间,如果将s8 a[100] = {0}; 这条语句去掉,还会占用200字节栈区空间。
现对于上面所述进行部分验证:
代码:
void get_info(s8 *info)
{
s8 *msg = "hello";
memcpy(info, msg, strlen(msg));
printf("@[%s] msg addr:%u\n", __FUNCTION__, (u32)&msg);
}
void indirect_call(void)
{
s8 a[8] = {0};
get_info(a);
printf("@[%s] a addr:%u a:%s\n", __FUNCTION__, (u32)a, a);
}
int main(void)
{
s8 a[8] = {0};
get_info(a);
printf("@[%s] a addr:%u a:%s\n", __FUNCTION__, (u32)a, a);
indirect_call();
s8 b[10] = {0};
printf("@[%s] b addr:%u\n", __FUNCTION__, (u32)b);
return 0;
}
|