example 1

int func(int a, int b, int c, int d, int e ,int f, int g)
{
    int h=10;
    int i;
    return a+b;
}

int main(int argc, char* argv[])
{
    func(1,2,3,4);
    return 3;
}

0000000000000608 <func>:
 608:   55                      push   %rbp //4. 保存旧rbp
 609:   48 89 e5                mov    %rsp,%rbp //5. rbp=rsp
 60c:   89 7d ec                mov    %edi,-0x14(%rbp) //6. 通过ebp来赋值栈,sp并没有变化
 60f:   89 75 e8                mov    %esi,-0x18(%rbp)
 612:   89 55 e4                mov    %edx,-0x1c(%rbp)
 615:   89 4d e0                mov    %ecx,-0x20(%rbp)
 618:   44 89 45 dc             mov    %r8d,-0x24(%rbp)
 61c:   44 89 4d d8             mov    %r9d,-0x28(%rbp)
 620:   c7 45 fc 0a 00 00 00    movl   $0xa,-0x4(%rbp) //7. 局部变量
 627:   8b 55 ec                mov    -0x14(%rbp),%edx
 62a:   8b 45 e8                mov    -0x18(%rbp),%eax
 62d:   01 d0                   add    %edx,%eax //8.计算,结果保存在eax
 62f:   5d                      pop    %rbp //9. sp此时还指向旧的rbp,相当于还原rbp
 630:   c3                      retq //10. pc=之前保存的返回地址.

0000000000000631 <main>:
 631:   55                      push   %rbp
 632:   48 89 e5                mov    %rsp,%rbp
 635:   48 83 ec 10             sub    $0x10,%rsp
 639:   89 7d fc                mov    %edi,-0x4(%rbp)
 63c:   48 89 75 f0             mov    %rsi,-0x10(%rbp)
 640:   6a 07                   pushq  $0x7 // 1.main->fun start here 从右往左,参宿入栈
 642:   41 b9 06 00 00 00       mov    $0x6,%r9d //2.其余参数先存直接寄存器,也可压栈
 648:   41 b8 05 00 00 00       mov    $0x5,%r8d
 64e:   b9 04 00 00 00          mov    $0x4,%ecx
 653:   ba 03 00 00 00          mov    $0x3,%edx
 658:   be 02 00 00 00          mov    $0x2,%esi
 65d:   bf 01 00 00 00          mov    $0x1,%edi
 662:   e8 a1 ff ff ff          callq  608 <func> //3.callq会保存返回地址,再调用func
 667:   48 83 c4 08             add    $0x8,%rsp
 66b:   b8 03 00 00 00          mov    $0x3,%eax
 670:   c9                      leaveq
 671:   c3                      retq
 672:   66 2e 0f 1f 84 00 00    nopw   %cs:0x0(%rax,%rax,1)
 679:   00 00 00
 67c:   0f 1f 40 00             nopl   0x0(%rax)

从步骤 6 来看,整个 sp 是没动过的,不用先减后加,而且局部变量借用了寄存器完成临时保存,先存到寄存器,再恢复到栈里.

example 2