printf是否使用C中的堆栈帧?
假设我们创建了一个用户函数void func()。 每当在其他函数(如main中调用时,func的堆栈帧都会通过函数调用进行分配 它与printf相同吗?printf是否使用C中的堆栈帧?,c,stack,printf,C,Stack,Printf,假设我们创建了一个用户函数void func()。 每当在其他函数(如main中调用时,func的堆栈帧都会通过函数调用进行分配 它与printf相同吗? printf是否也使用堆栈帧?函数的堆栈帧由该函数保留;当然,没有其他函数可以知道另一个函数的堆栈使用需求 因此,当您从main()调用func()时,func()中的代码(有时称为“序言”)将保留该函数所需的堆栈空间 是的,这适用于所有函数,包括printf()函数的堆栈帧由该函数保留;当然,没有其他函数可以知道另一个函数的堆栈使用需求 因
printf是否也使用堆栈帧?函数的堆栈帧由该函数保留;当然,没有其他函数可以知道另一个函数的堆栈使用需求 因此,当您从
main()
调用func()
时,func()
中的代码(有时称为“序言”)将保留该函数所需的堆栈空间
是的,这适用于所有函数,包括
printf()
函数的堆栈帧由该函数保留;当然,没有其他函数可以知道另一个函数的堆栈使用需求
因此,当您从main()
调用func()
时,func()
中的代码(有时称为“序言”)将保留该函数所需的堆栈空间
是的,这适用于所有函数,包括
printf()
前提:堆栈帧只是许多C实现的一个实现细节(具体来说,它通常在x86上使用);它既不是C标准所需要的(C标准对堆栈一无所知),也不是所有实现所需要的(甚至不是,它甚至可能取决于编译器标志/优化器的考虑)
当然,库函数最终只是已经编译到标准库中的常规函数,因此在这方面没有什么特别之处:在使用堆栈帧的实现中,每当执行函数调用时,被调用函数都会设置其堆栈帧(除非它是内联的或完全不重要,但对于像printf
这样的库函数,通常不会发生这种情况)
不过,这也没什么好担心的——当函数返回时,新的堆栈帧将被丢弃,其堆栈空间将再次可用,因此您不必小心不要调用太多函数。前提:堆栈帧只是许多C实现的一个实现细节(具体来说,它通常在x86上使用);它既不是C标准所要求的(C标准对堆栈一无所知),也不是所有实现所需要的(甚至不是,它甚至可能取决于编译器标志/优化器的考虑) 当然,库函数最终只是已经编译到标准库中的常规函数,因此在这方面没有什么特别之处:在使用堆栈帧的实现中,每当执行函数调用时,被调用函数都会设置其堆栈帧(除非它是内联的或完全不重要,但对于像
printf
这样的库函数,通常不会发生这种情况)
不过,这也没什么好担心的——当函数返回时,新的堆栈帧被丢弃,其堆栈空间再次可用,因此您不必小心不要调用太多函数。这里是一个带有
main
的小代码,它调用了一个名为func
的简单函数
我们可以使用gcc main.c-S main.S
编译这个c代码。main.S应该是一个程序集输出
在程序集中,您可能会看到CPU指令:push、pop、leave、enter。这些指令负责堆栈帧管理
如果使用gcc和其他选项进行编译,您可能会注意到一些堆栈管理差异
#include <stdio.h>
int func(void);
int func(void)
{
int i;
for(i=0;i<100;i++)
printf("%d",i);
return i;
}
int main(void)
{
return func();
}
这里函数func
(objdump main.o-S
).main.o的objdump输出是通过以下方式获得的:gcc main.c-o main.o
000000000040052d <func>:
40052d: 55 push %rbp
40052e: 48 89 e5 mov %rsp,%rbp
400531: 48 83 ec 10 sub $0x10,%rsp
400535: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%rbp)
40053c: eb 18 jmp 400556 <func+0x29>
40053e: 8b 45 fc mov -0x4(%rbp),%eax
400541: 89 c6 mov %eax,%esi
400543: bf f4 05 40 00 mov $0x4005f4,%edi
400548: b8 00 00 00 00 mov $0x0,%eax
40054d: e8 be fe ff ff callq 400410 <printf@plt>
400552: 83 45 fc 01 addl $0x1,-0x4(%rbp)
400556: 83 7d fc 63 cmpl $0x63,-0x4(%rbp)
40055a: 7e e2 jle 40053e <func+0x11>
40055c: 8b 45 fc mov -0x4(%rbp),%eax
40055f: c9 leaveq
400560: c3 retq
0000000000400561 <main>:
400561: 55 push %rbp
400562: 48 89 e5 mov %rsp,%rbp
400565: e8 c3 ff ff ff callq 40052d <func>
40056a: 5d pop %rbp
40056b: c3 retq
40056c: 0f 1f 40 00 nopl 0x0(%rax)
0000000000 40052D:
40052d:55%推送rbp
40052e:48 89 e5 mov%rsp,%rbp
400531:48 83 ec 10子$0x10,%rsp
400535:c7 45 fc 00移动$0x0,-0x4(%rbp)
40053c:eb 18 jmp 400556
40053e:8b 45 fc mov-0x4(%rbp),%eax
400541:89 c6 mov%eax,%esi
400543:bf f4 05 40 00 mov$0x4005f4,%edi
400548:b8 00 mov$0x0,%eax
40054d:e8 fe ff ff callq 400410
400552:83 45 fc 01 addl$0x1,-0x4(%rbp)
400556:83 7d fc 63 cmpl$0x63,-0x4(%rbp)
40055a:7e e2 jle 40053e
40055c:8b 45 fc mov-0x4(%rbp),%eax
40055f:c9-Q
400560:c3 retq
0000000000400561 :
400561:55%按需付费
400562:48 89 e5 mov%rsp,%rbp
400565:e8 c3 ff ff ff callq 40052d
40056a:5d pop%rbp
40056b:c3 retq
40056c:0f 1f 40 00 nopl 0x0(%rax)
这里是一个带有main
的小代码,它调用一个名为func
的简单函数
我们可以使用gcc main.c-S main.S
编译这个c代码。main.S应该是一个程序集输出
在程序集中,您可能会看到CPU指令:push、pop、leave、enter。这些指令负责堆栈帧管理
如果使用gcc和其他选项进行编译,您可能会注意到一些堆栈管理差异
#include <stdio.h>
int func(void);
int func(void)
{
int i;
for(i=0;i<100;i++)
printf("%d",i);
return i;
}
int main(void)
{
return func();
}
这里函数func
(objdump main.o-S
).main.o的objdump输出是通过以下方式获得的:gcc main.c-o main.o
000000000040052d <func>:
40052d: 55 push %rbp
40052e: 48 89 e5 mov %rsp,%rbp
400531: 48 83 ec 10 sub $0x10,%rsp
400535: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%rbp)
40053c: eb 18 jmp 400556 <func+0x29>
40053e: 8b 45 fc mov -0x4(%rbp),%eax
400541: 89 c6 mov %eax,%esi
400543: bf f4 05 40 00 mov $0x4005f4,%edi
400548: b8 00 00 00 00 mov $0x0,%eax
40054d: e8 be fe ff ff callq 400410 <printf@plt>
400552: 83 45 fc 01 addl $0x1,-0x4(%rbp)
400556: 83 7d fc 63 cmpl $0x63,-0x4(%rbp)
40055a: 7e e2 jle 40053e <func+0x11>
40055c: 8b 45 fc mov -0x4(%rbp),%eax
40055f: c9 leaveq
400560: c3 retq
0000000000400561 <main>:
400561: 55 push %rbp
400562: 48 89 e5 mov %rsp,%rbp
400565: e8 c3 ff ff ff callq 40052d <func>
40056a: 5d pop %rbp
40056b: c3 retq
40056c: 0f 1f 40 00 nopl 0x0(%rax)
0000000000 40052D:
40052d:55%推送rbp
40052e:48 89 e5 mov%rsp,%rbp
400531:48 83 ec 10子$0x10,%rsp
400535:c7 45 fc 00移动$0x0,-0x4(%rbp)
40053c:eb 18 jmp 400556
40053e:8b 45