C函数调用分析

1. 之前只知道程序都是从从main()函数开始执行,然后在内部调用其它函数,但一直不理解其内部机理,今天借此机会来分析一下其中的原理,看看内存里面到底怎么运行的

2.我们以一个最简单的程序为例来分析

分析平台:ubuntu16.04

编译环境:GCC

分析工具:gdb

创建一个文件:mkdir test; 再创建一个文件touch add.c,输入一下代码

  • #include<stdio.h>
    int Add(int x, int y)
    {
        int z = 0;
        z = x + y;
        return z;
    }

    int main()
    {
        int a = 10;
        int b = 20;
        int c = Add(a, b);
        return 0;
    }

  • 借此我们来回顾一下编译过程:预编译、编译、汇编、链接

  • OK,开始来编译程序,为了了解其中每一个不走,我生成了每个过程的文件

  • 预编译:gcc -E -o add.i add.c   生成了add.i文件

  • 编译:gcc -S add.i  生成add.s文件,此为汇编文件

  • 汇编:gcc -c  add.i 生成add.o文件

  • 链接:gcc add.o -o add

  • 感兴趣的可以去查看每个步骤生成的文件是什么

3. gdb调试

用gdb -version查看是否安装了gdb工具,如果没有安装的话用sudo apt-get install gdb来安装

然后输入gdb进入调试界面

然后输入file add

此时发现

这个问题,原来是bian编译过程中没有加入-g命令,那么我们重新编译一下 gcc -g -c -o add add.c

gdb

file add

没问题了,我们先来查看main函数的反汇编代码

disas main

emmm,好像全是汇编ming命令,不用担心,我们一点点来分析

+0  rbp,在64位系统中是栈底指针,当然,我们一般认为栈是向下增长的

+1 将rsp指向rbp,这是一个初始化的过程吧,代表栈空

+4 rsp=rsp-16,分配16个字节的栈空间,

+8 我们程序中定义了一个变量a = 10, 放在 rbp -12的位置

+15 b=20放在rbp -8的位置

+22 将b的值放入edx(数据寄存器)里

+25 将a的值放入eax(累加ji寄存器)里

+28 edx -> esi(bi变址寄存器)

+30 eax-> edi

+32 调用Add函数了,我们接下来分析Add函数

disad Add

然后建立Add函数函数自己的堆栈,建立形参x,y的空间,然后是局部变量z,将传入的参数相加后放在eaxji寄存器里,最后最后将eax的值保存在z里,但是Add函数diao调用完成后会销毁栈,那返回值怎么传给main()函数呢,+28又将z的值放在eax里了,这样当Add函数结束后main函数还能去eaxji'c寄存器里取这个值

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值