gpt4 book ai didi

c - 字符串在栈上的分配

转载 作者:太空宇宙 更新时间:2023-11-04 00:33:16 24 4
gpt4 key购买 nike

我在堆栈上分配了 12 个字符字符串,或者说它是 12 个字节。

使用 gdb(在 Linux 下)反汇编表明,为了在堆栈上为字符串分配空间,esp 移动了 -24(在堆栈下)。

push   %ebp
mov %esp,%ebp
sub $0x18,%esp

为什么移动24(0x18)?

最佳答案

如果您的函数调用其他函数,其中一些可能是传出参数的空间;其中一些可能是溢出寄存器的值的临时空间;其中一些可能是填充。这将非常依赖于编译器版本和优化标志。

下面是一些简单的废话代码来说明:

extern int foo(int a, int b);

int bar(int c)
{
char s[12];

s[0] = foo(c, 123);
return 456;
}

这里是在 Debian Lenny 机器上使用 gcc 4.3.2 编译的,没有优化:

bar:
pushl %ebp
movl %esp, %ebp
subl $24, %esp
movl $123, 4(%esp)
movl 8(%ebp), %eax
movl %eax, (%esp)
call foo
movb %al, -12(%ebp)
movl $456, %eax
leave
ret

与您的代码一样,它分配了 24 个字节。以下是它们的用途:

     Stack while running bar()    :                         :    +-------------------------+    | incoming parameter: c   | 8(%ebp)    +-------------------------+            ---    | return address          | 4(%ebp)     ^    +-------------------------+             |    | old %ebp                | (%ebp)      |    +-------------------------+             |  bar()'s stack    | s[8]..s[11]             | -4(%ebp)    | frame: 32 bytes    +-------------------------+             |    | s[4]..s[7]              | -8(%ebp)    |    +-------------------------+             |    | s[0]..s[3]              | -12(%ebp)   |    +-------------------------+             |     Stack while running foo()    | (unused)                | 8(%esp)     |    :                         :    +-------------------------+             |    +-------------------------+    | outgoing parameter: 123 | 4(%esp)     |    | incoming parameter: b   |    +-------------------------+             |    +-------------------------+    | outgoing parameter: c   | (%esp)      v    | incoming parameter: a   |    +-------------------------+            ---   +-------------------------+                                                 | return address          |                                                 +-------------------------+                                                 | old %ebp                |                                                 +-------------------------+                                                 : locals for foo()        :

一些实验表明,如果增加s[],它会占用未使用的空间;例如如果它是 13 个字节,则堆栈帧大小相同,但 s[] 将提前一个字节开始(在 -13(%ebp))- 最多 16字节,其中所有分配的堆栈将实际使用。如果 s 声明为 s[17],编译器将分配 40 字节的堆栈而不是 24。

这是因为编译器将堆栈帧的总大小(上图左侧的所有内容,传入参数除外,它实际上位于调用者堆栈帧的底部)四舍五入为16 个字节。 (有关 -mpreferred-stack-boundary 选项,请参阅 gcc 文档。)

关于c - 字符串在栈上的分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4270756/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com