什么是 c/c++ 数据段和堆栈大小?

Wha*_*tIf 6 c++ linux stack gcc data-segment

我读到它取决于编译器和操作系统架构。如何在使用 GCC 作为编译器的 Linux 系统上找出数据段和堆栈最大大小?

Kon*_*rov 6

让我和你一起试验:像这样创建文件“test.c”:

int main (void) { return 0; }
Run Code Online (Sandbox Code Playgroud)

现在编译它,指定最大堆栈大小(只是为了在映射文件中轻松查找这个数字并确定符号名称,参考它):

gcc test.c -o test.x -Wl,--stack=0x20000 -Wl,-Map=output.map
Run Code Online (Sandbox Code Playgroud)

确定数据大小很简单:

size -A -d test.x
Run Code Online (Sandbox Code Playgroud)

你会得到这样的东西:

section           size         addr
.text             1880   4299165696
.data              104   4299169792
...
Run Code Online (Sandbox Code Playgroud)

``objdump -h test.x'' 也可以正常工作,但结果不那么冗长。

这里有更多的部分(不仅仅是代码和数据),但这里没有堆栈信息。为什么?因为堆栈大小不是 ELF 部分,所以只有在您的程序加载执行后才会保留它。您应该从文件中的某个(平台相关)符号中读取它,如下所示:

$ nm test.x  | grep __size_of_stack_reserve__
0000000000020000 A __size_of_stack_reserve__
Run Code Online (Sandbox Code Playgroud)

毫不奇怪,这个大小是 0x20000,正如编译时所说的那样。

我通过查看编译期间生成的 output.map 文件来确定符号名称。我建议您也从查看它开始。

接下来,当您确实有一些未知文件 a.out 时,只需重复序列:

size -A -d a.out
nm a.out | grep __size_of_stack_reserve__
Run Code Online (Sandbox Code Playgroud)

将平台相关符号替换为您在实验中确定的符号,如上所述。


Tho*_*ews 4

段是一种组织可执行文件所需内容的方法。

数据段通常用于可执行文件使用的任何数据(无需从外部源输入)。某些数据段可能包含字符串文字或数字常量。

许多可执行文件使用堆栈来存储函数局部变量、语句块局部变量、返回地址和函数参数。C 或 C++ 语言不需要堆栈;它只是一个方便的数据结构。

堆栈大小可以是分配给堆栈的容量,也可以是驻留在堆栈上的元素数量或堆栈占用的内存量。

许多平台都有堆栈的默认大小。由于平台不同,您需要阅读工具的文档,了解如何设置堆栈大小以及默认容量是多少。