Home  >  Q&A  >  body text

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

我的理解是静态编译时,因为C语言是过程性语言只能静态联编不能动态联编,而C++编译于此类似,所以是编译时完全。不知道这样对不对?

天蓬老师天蓬老师2763 days ago802

reply all(3)I'll reply

  • 阿神

    阿神2017-04-18 10:50:16

    The order of pushing onto the stack is determined at compile time.

    The main thing that needs to be pushed onto the stack before a function call is the function parameters, and the parameters are all fixed (the variable parameters are just offsets determined by macros).
    The code for calling functions is placed in the code segment, and pushing onto the stack is done in the form of instructions, so the order is determined at compile time.

    reply
    0
  • 阿神

    阿神2017-04-18 10:50:16

    @lianera is right, the order of pushing onto the stack is determined at compile time.

    Let me show you an example:
    I have a piece of code like this

    #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;
    }

    After compilation, his assembly code looks like this

    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    rrreeex20,%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   rrreeex3,-0xc(%rbp)
      // 压入本地变量B
        B = 4;
      40049f:    c7 45 f8 04 00 00 00     movl   rrreeex4,-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    rrreeex1,%eax
    }
    

    It doesn’t matter if you don’t understand assembly. During the compilation process, the order in which parameters are passed, and where on the stack (relative position) the parameters, local variables, etc. should be placed are all determined. When the program runs to the corresponding program, the stack will be operated in the compiled order.

    reply
    0
  • PHP中文网

    PHP中文网2017-04-18 10:50:16

    Isn’t pushing onto the stack a process that only occurs at runtime? Compilation is just a process of translating into bytecode. Why is there pushing on the stack?

    reply
    0
  • Cancelreply