我正在编写一些具有64 MB SDRAM的嵌入式设备。 (C用作编程语言)。 关于这个设备堆栈的可能大小是否可能猜测(甚至可能是一个粗略的猜测)? 参考在我们进行分配时使用的存储器,例如,
char s[100];
int t[50];
等
例如,它会超过50KB吗?等我粗暴的意思加上我在某个函数f中有变量
f()
{
int p;
}
当f()存在时,这个变量死了吗?
所以当我调用f2()时:
void f2()
{
char t[100];
}
只有100个元素字符数组的大小才会被添加到堆栈大小对吗?
不再考虑先前函数的int p
大小。
答案 0 :(得分:4)
可以进行各种猜测:)大多数(全部?)嵌入式开发环境提供了分配设备内存的机制(只读,堆栈,堆等)。这通常通过链接器指令文件或C #pragmas来完成。放在设置源文件中。如果没有关于开发环境的更多信息,则无法做出准确的猜测。
在函数f()
中,变量p
将存在于堆栈中。当函数退出时,堆栈上的该位置可能会用于其他内容。
对于函数f2()
,当执行此函数时,可以预期堆栈中的100个字节将分配给t
。 <{1}}的大小将不予考虑。
请注意,堆栈可用于其他信息,因此您无法在不考虑其他因素的情况下可靠地估计堆栈使用情况。例如,你期望递归吗?堆栈可用于存储函数调用/返回信息 - 从而减少本地(堆栈)变量的空间量。
最后,我使用堆栈少于1KB的设备,所以应该仔细考虑。
答案 1 :(得分:1)
你的问题看起来像是“猜测堆栈大小”
为什么猜你什么时候才能知道它不是从天而降! :)
对于嵌入式程序员来说,堆栈大小始终在他手中,必须通过他提交给加载器的链接器命令文件来处理它
如下所示
Linker.cmd
MEMORY
{
.
.
SARAM2 (RWIX) : origin = 0x039000, length = 0x010000 /*64KB*/
.
.
}
SECTIONS
{
.
.
.stack > SARAM2
.sysstack > SARAM2
.
.
}
所以很清楚你可以设置自己的堆栈大小,“堆栈大小限制为堆栈指针绑定”
所以它完全取决于你的堆栈指针范围,如果你的堆栈指针是16位,你的堆栈大小限制为2 ^ 16,这是64KB
例如,在标准的linux机器中,远离固件编程 如果你去打字ulimit -a
你将获得有限的堆栈大小,并且它可以扩展到Stack Pointer可以指向的边界
BTW这些可能会进一步帮助您
When Does Stack Really Over Flow
我还建议监视你的堆栈大小并不是一个坏主意,换句话说,试图找到堆栈指针值可以让你清楚'你的堆栈状态是什么?',特别是对于嵌入式程序员来说堆栈溢出的原因严重损坏:)
答案 2 :(得分:0)
Linux内核源代码中有一个脚本可以帮助您找到在堆栈上大量分配的函数。该脚本名为checkstack.pl
,位于scripts
目录中。
以下是一个示例调用:
$ objdump -d $BUILDDIR/target-isns | perl checkstack.pl x86_64
0x00403799 configfs_handle_events []: 4384
0x004041d6 isns_attr_query []: 4176
0x00404646 isns_target_register []: 4176
该脚本显示占用堆栈空间最多的函数。该脚本可以帮助您猜测所需的堆栈大小。此外,它还可以帮助您确定哪些功能应根据其堆栈使用情况进行优化。
答案 3 :(得分:0)
您可能会发现链接器能够执行堆栈需求分析 - 通常通过命令行选项指定映射文件内容。如果您可以添加有关工具链的信息,您将获得更好的建议。
这样的分析给出的是最坏情况下的堆栈使用情况以及任何特定函数所涉及的调用路径 - 对于进程总计,您需要查看main()和任何其他线程入口点(每个进程点)的堆栈使用情况将有一个单独的堆栈)。您可能还需要考虑在某些目标上可能使用中断进程或线程堆栈的ISR,在其他目标上可能存在单独的中断堆栈。
在递归或通过函数指针调用的情况下,哪些链接器堆栈分析无法确定堆栈使用情况,这两者都取决于无法静态确定的主要运行时条件。