为了账号安全,请及时绑定邮箱和手机立即绑定

C,C++函数调用时入栈顺序 是编译时还是运行时完成的?

C,C++函数调用时入栈顺序 是编译时还是运行时完成的?

智慧大石 2019-02-22 01:22:06
我的理解是静态编译时,因为C语言是过程性语言只能静态联编不能动态联编,而C++编译于此类似,所以是编译时完全。不知道这样对不对?
查看完整描述

3 回答

?
绝地无双

TA贡献1946条经验 获得超4个赞

入栈的顺序是编译时确定的。

函数调用之前需要入栈的主要是函数参数,而参数都是固定的(可变参数只是用宏确定偏移量)。
调用函数的代码是放在代码段的,入栈都是以指令方式进行的,所以顺序都是编译时确定的。

查看完整回答
反对 回复 2019-03-01
?
UYOU

TA贡献1878条经验 获得超4个赞

@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
}

不懂汇编也没关系,在编译过程中,参数的传递顺序,参数、本地变量等应该放在栈的哪个位置(相对位置)都是定了的。当程序运行到相应程序后会按照编译好的顺序对栈进行操作。

查看完整回答
反对 回复 2019-03-01
?
慕哥6287543

TA贡献1831条经验 获得超10个赞

入栈这个不是运行时才有的过程吗?编译只是翻译为字节码的过程,为什么会有入栈?

查看完整回答
反对 回复 2019-03-01
  • 3 回答
  • 0 关注
  • 1023 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信