浅析函数之间的调用关系


一个函数的调用包括将数据(以参数和返回值形式)和控制代码的一部分传递到另一部分。在函数调用是,必须为被调用的函数的局部变量分配空间,并在退出时释放这些空间。参数传递和被局变量的分配和释放空间则是通过操纵程序栈来实现。

那么我们则得了解一个函数栈的结构:

机器用栈来传递函数参数,存储返回信息,保存寄存器用于以后恢复,以及本地存储。下图则是一个简单的栈帧结构:


上图我们看到了两个重要的指针,分别是%esp(栈指针),%ebp()帧指针,也叫基址指针,其中%esp永远指向栈顶,而%ebp 主要用于访问变量,下面我们通过一个简单的程序来了解下函数的调用(ubunt64 位编译):

源代码:

int be_called(int*,int*);
int caller()
{
    int a =1;
    int b = 2;
    be_called(&a,&b);
    return 0;
}
int be_called( int *a, int *b )
{
    int rtrn_val;
    rtrn_val = *a + *b;

    return rtrn_val;

}

汇编代码:

64位系统 栈指针 rsp, 帧指针rbp

caller:
.LFB0:
    .cfi_startproc
    pushq    %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    subq    $16, %rsp
    movl    $1, -8(%rbp)  // (rbp-8)
    movl    $2, -4(%rbp)  //
    leaq    -4(%rbp), %rdx
    leaq    -8(%rbp), %rax
    movq    %rdx, %rsi    // &b  ps:由于是64位CPU系统,使用了寄存器传参 ,- -!
    movq    %rax, %rdi    // &a

    call    be_called
    movl    $0, %eax
    leave
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc


be_called:
.LFB1:
    .cfi_startproc
    pushq    %rbp                 // store rbp
    .cfi_def_cfa_offset 16      // 关于这个值为16,可以看这里解释http://stackoverflow.com/questions/7534420/gas-explanation-of-cfi-def-cfa-offset
    .cfi_offset 6, -16
    movq    %rsp, %rbp          //set rbp  = rsp
    .cfi_def_cfa_register 6
    movq    %rdi, -24(%rbp) //&a 
    movq    %rsi, -32(%rbp) //&b
    movl    $0, -4(%rbp)       // 临时变量rtrn_val = 0; &rtrn_val  = rbp -4
    movq    -24(%rbp), %rax
    movl    (%rax), %edx
    movq    -32(%rbp), %rax
    movl    (%rax), %eax
    addl    %edx, %eax               
    movl    %eax, -4(%rbp)
    movl    -4(%rbp), %eax          // rtrn_val  = *a + *b
    popq    %rbp                         // restore rbp
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc


嗯,大概就是这样,貌似64位系统没有很好的表现出了上面那张图,不过其实理解起来擦不多 大笑





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值