概述
转载请注明来源 http://blog.csdn.net/imred/article/details/48865359
初学C语言的时候,我们有时会听说函数调用会有一定的开销,在进行了进一步学习之后,我们来看看原来听说的开销指的什么。
下面是两个非常简单的样例,就不作解释了:
函数调用版本C程序:
#include <stdio.h>
int sum(int a, int b)
{
return a + b;
}
int main()
{
int a = 1;
int b = 1;
int c;
c = sum(a, b);
return 0;
}
使用gcc汇编后:
.file
"function.c"
.text
.globl
_sum
.def
_sum;
.scl
2;
.type
32; .endef
_sum:
pushl
%ebp
movl
%esp, %ebp
movl
12(%ebp), %eax
movl
8(%ebp), %edx
addl
%edx, %eax
popl
%ebp
ret
.def
___main;
.scl
2;
.type
32; .endef
.globl
_main
.def
_main;
.scl
2;
.type
32; .endef
_main:
pushl
%ebp
movl
%esp, %ebp
andl
$-16, %esp
subl
$32, %esp
call
___main
movl
$1, 28(%esp)
movl
$1, 24(%esp)
movl
24(%esp), %eax
movl
%eax, 4(%esp)
movl
28(%esp), %eax
movl
%eax, (%esp)
call
_sum
movl
%eax, 20(%esp)
movl
$0, %eax
leave
ret
无函数调用版本c程序:
#include <stdio.h>
int main()
{
int a = 1;
int b = 1;
int c;
c = a + b;
return 0;
}
使用gcc汇编后:
.file
"no_function.c"
.def
___main;
.scl
2;
.type
32; .endef
.text
.globl
_main
.def
_main;
.scl
2;
.type
32; .endef
_main:
pushl
%ebp
movl
%esp, %ebp
andl
$-16, %esp
subl
$16, %esp
call
___main
movl
$1, 12(%esp)
movl
$1, 8(%esp)
movl
8(%esp), %eax
movl
12(%esp), %edx
addl
%edx, %eax
movl
%eax, 4(%esp)
movl
$0, %eax
leave
ret
除了公共部分和指导信息之外,第一个汇编程序比第二个汇编程序多了以下内容:
1
movl
24(%esp), %eax
movl
%eax, 4(%esp)
movl
28(%esp), %eax
movl
%eax, (%esp)
2
call
_sum
3
pushl
%ebp
movl
%esp, %ebp
4
popl
%ebp
ret
额外的开销就体现在这4段代码上了,我来一一解释一下它们的作用:
1
参数入栈代码,将函数参数入栈,这是现在函数调用的标准方式。参数越多,开销越大
2
将控制权转移至函数中
3
建立新的栈帧,也就是当前函数使用的“一片”栈空间,使用ebp的值来标识新的栈帧,因此要将原栈帧首地址保存下来,方便回到原来的即调用者的栈帧
4
恢复原栈帧,然后将控制权转移至调用者
从汇编的角度来看,这额外的开销就是指的这不足十行的指令了,会对性能有多大影响呢?大概有那么一丁点。当然,对于不同的函数,以及不同的调用频率,这个影响也不尽相同。当然,这个程序是一个极端,它函数的功能代码也只有3行,这样的情况完全可以不用函数或者使用内联函数。所以是使用函数还是不使用函数呢?依我来看,为了程序的可读性,我们还是牺牲那么一丁点的性能吧。
转载请注明来源 http://blog.csdn.net/imred/article/details/48865359
最后
以上就是无情皮卡丘为你收集整理的C语言: 函数调用的开销的全部内容,希望文章能够帮你解决C语言: 函数调用的开销所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复