函数调用开销
函数调用 开销
2023-09-14 09:06:32 时间
做了几个实验,简单学习了解一下函数调用的开销。
程序1—没有参数的函数调用:
[cpp] view plaincopyprint?
#include <stdio.h>
void test()
{
return;
}
int main(int argc, char *argv[])
{
test();
return 0;
}
用gcc -S得到程序1的汇编代码:
- .file "test.c"
- .text
- .globl test
- .type test, @function
- test:
- pushl %ebp
- movl %esp, %ebp
- nop
- popl %ebp
- ret
- .size test, .-test
- .globl main
- .type main, @function
- main:
- pushl %ebp
- movl %esp, %ebp
- call test
- movl $0, %eax
- popl %ebp
- ret
- .size main, .-main
- .ident "GCC: (GNU) 4.5.1 20100924 (Red Hat 4.5.1-4)"
- .section .note.GNU-stack,"",@progbits
从上面汇编代码可以看出,对于没有参数函数调用的开销:
1. 调用函数和返回,所以需要执行一次call/ret指令对。
2. 函数内部,需要保护现场,所以需要把%ebp push到栈中,返回前,再pop出来。
3. 构造函数运行环境,将%ebp赋值为当前的栈顶%esp。
则没有参数函数调用开销是5个指令。
程序2-带参数函数调用:
- #include <stdio.h>
- void test(int a)
- {
- (a)++;
- return;
- }
- int main(int argc, char *argv[])
- {
- int a = 1;
- test(a);
- return 0;
- }
用gcc -S得到程序2的汇编代码:
- .file "test.c"
- .text
- .globl test
- .type test, @function
- test:
- pushl %ebp
- movl %esp, %ebp
- addl $1, 8(%ebp)
- nop
- popl %ebp
- ret
- .size test, .-test
- .globl main
- .type main, @function
- main:
- pushl %ebp
- movl %esp, %ebp
- subl $20, %esp
- movl $1, -4(%ebp)
- movl -4(%ebp), %eax
- movl %eax, (%esp)
- call test
- movl $0, %eax
- leave
- ret
- .size main, .-main
- .ident "GCC: (GNU) 4.5.1 20100924 (Red Hat 4.5.1-4)"
- .section .note.GNU-stack,"",@progbits
相比于没有参数函数调用的开销,带参数函数调用多2个指令,用于传递参数:
movl -4(%ebp), %eax
movl %eax, (%ebp)
每个参数的传递时都需要2个指令。
而如果是指针参数,则函数在使用时,还得需要2个指令。
这么看,函数调用的开销还挺大的。
所以,当一个函数很小且调用频繁时,应该用宏或内联函数进行替代。
另外,虽然函数调用有开销,但除非有特殊的必要,该用函数的地方还是应该使用函数,否则会严重降低代码的可读性和可维护性。
相关文章
- oracle函数的调用应使用execute命令_matlab函数调用
- c语言调用循环内部函数,通达信绘图函数调用,通达信调用内部数据[通俗易懂]
- 【GCC编译优化系列】究竟什么样的代码会导致函数调用的栈溢出呢?
- CGO学习二,基本数据类型转换2 和 函数调用
- eBPF 入门开发实践指南五:在 eBPF 中使用 uprobe 捕获 bash 的 readline 函数调用
- 【Android 逆向】x86 CPU 架构体系 ( 堆内存 | 栈内存 | 函数调用 )
- 【Android 逆向】x86 汇编 ( call 子函数调用指令 | jmp 跳转指令 | lea 加载指令 | mov 数据传送指令 )
- Linux中的函数调用机制(linux函数调用)
- JS函数调用(4种方法)
- Linux中优雅的函数调用体验(linux中函数调用函数)
- 「MySQL自定义函数的使用方法」(mysql自定义函数调用)
- JavaScript函数调用规则
- JS嵌套函数调用上下文的问题解决