java - C,C++函数调用时入栈顺序 是编译时还是运行时完成的?
问题描述
我的理解是静态编译时,因为C语言是过程性语言只能静态联编不能动态联编,而C++编译于此类似,所以是编译时完全。不知道这样对不对?
问题解答
回答1:入栈的顺序是编译时确定的。
函数调用之前需要入栈的主要是函数参数,而参数都是固定的(可变参数只是用宏确定偏移量)。 调用函数的代码是放在代码段的,入栈都是以指令方式进行的,所以顺序都是编译时确定的。
回答2:@lianera 说的不错,入栈的顺序是编译时确定的。
我这给你看个例子:我有段代码是这样的
#include <stdio.h>int test_fun(int a, int b){ return a + b; }int main(int argc, char *argv[]){ int A, B, ret; A = 3; B = 4; ret = test_fun(A, B); return 1;}
编译后,他的汇编代码是这样的
int test_fun(int a, int b){ 400474: 55 push %rbp 400475: 48 89 e5 mov %rsp,%rbp // $edi存的是A的值,$esi存的是B的值,将他们压入栈中 400478: 89 7d fc mov %edi,-0x4(%rbp) 40047b: 89 75 f8 mov %esi,-0x8(%rbp) return a + b; 40047e: 8b 45 f8 mov -0x8(%rbp),%eax 400481: 8b 55 fc mov -0x4(%rbp),%edx 400484: 8d 04 02 lea (%rdx,%rax,1),%eax}int main(int argc, char *argv[]){ 400489: 55 push %rbp 40048a: 48 89 e5 mov %rsp,%rbp 40048d: 48 83 ec 20 sub $0x20,%rsp 400491: 89 7d ec mov %edi,-0x14(%rbp) 400494: 48 89 75 e0 mov %rsi,-0x20(%rbp) int A, B, ret; // 压入本地变量A A = 3; 400498: c7 45 f4 03 00 00 00 movl $0x3,-0xc(%rbp) // 压入本地变量B B = 4; 40049f: c7 45 f8 04 00 00 00 movl $0x4,-0x8(%rbp) ret = test_fun(A, B); 4004a6: 8b 55 f8 mov -0x8(%rbp),%edx 4004a9: 8b 45 f4 mov -0xc(%rbp),%eax // 将A和B的值放入相应的寄存器 4004ac: 89 d6 mov %edx,%esi 4004ae: 89 c7 mov %eax,%edi // 调用test_fun 4004b0: e8 bf ff ff ff callq 400474 <test_fun> 4004b5: 89 45 fc mov %eax,-0x4(%rbp) return 1; 4004b8: b8 01 00 00 00 mov $0x1,%eax}
不懂汇编也没关系,在编译过程中,参数的传递顺序,参数、本地变量等应该放在栈的哪个位置(相对位置)都是定了的。当程序运行到相应程序后会按照编译好的顺序对栈进行操作。
回答3:入栈这个不是运行时才有的过程吗?编译只是翻译为字节码的过程,为什么会有入栈?
相关文章:
1. java - c++ 通过jni创建jvm比直接启动jar要卡很多?2. java - canvas的问题,如何画出组合图形3. java - Ckeditor上传图片时出现mutipartRequest 转换异常4. java - CMS 富文本文章存储方式5. java - c++ stl模板参数可以赋值?6. java - ConcurrentHashMap中的get()方法为什么可以不加锁?7. java - CompletableFuture allof 超时处理8. java - C语言的一道算法题-兄弟郊游问题 求解?9. java - C++ ostringstream问题10. java - Cannot resolve symbol ‘HttpServletRequest’