首页 技术 正文
技术 2022年11月17日
0 收藏 443 点赞 4,880 浏览 1123 个字

C语言函数调用详细过程

函数调用是步骤如下:

  1. 按照调用约定传参

    • 调用约定是调用方(Caller)和被调方(Callee)之间按相关标准

      对函数的某些行为做出是商议,其中包括下面内容:

      传参顺序:是从左往右传还是从右往左

      传参方式:是用寄存器传还是使用内存传

      平栈方式:是调用方平栈还是被调方平栈

      返回值的传递方式:是用寄存器传还是使用内存传

    • 什么是堆桟?

      一个程序运行的时候,它的进程的地址空间一般可以分为四块:

      代码区,数据区,堆,栈,每块功能如下:

      区域 功能
      代码区 存放函数被编译后的二进制可执行代码
      数据区 只读区:存放常量,例如:常量字符串,const修饰的全局变量等
      可读写区:存放全局变量和静态变量
      除去其他三个区域,剩下的都是堆,不连续
      存放函数运行时所需的参数,寄存器环境,返回值,局部变量

    以下面代码为例:

        int  TestFunction(char szBuff[],int nSize)
    {
    for (int iIndex = 0; iIndex < nSize; iIndex++)
    {
    szBuff[iIndex] = 'x';
    }
    return 3;
    } int main()
    {
    char szBuff[32] = { "sfjdlskfjl" };
    int nRet = TestFunction(szBuff, 32);
    return 0;
    }

    函数参数参数传递:

    从上图中可以看出函数参数入栈

  2. 保存返回地址(紧挨着被调用函数的下一行可执行代码的内存地址)

    从上图中可以看出函数调用完成后,紧挨着的第一条指令为:

    00EB175B add esp,8

    所以,参数传递完成后就是返回值入栈:

  3. 程序流程转移到被调用函数地址处

  4. 保存调用方栈底

  5. 切换到当前函数(被调用函数)的栈底

    调用方栈底保存完成后,当前的栈顶(ESP记录的地址)就成为被调用函数的栈底

  6. 为局部变量分配空间

    这里程序为调试版本,所以为局部变量分配的空间比较大,在Release版本中

    会根据局部变量实际所需空间来分配大小

  7. 保存寄存器环境

    这里一共保存了3个寄存器,共12字节,在Release版本下,只保存两个

    在Debug版程序中(有/Zi(带有调试信息)和/Od(禁止优化)编译命令),除了为

    局部变量分配较大的内存空间外,还会将分配的局部变量空间全部置为0xCC:

    这种填充方式比较直观,能够让我们在调试时直观的观察到是否发生越界等错误

  8. 开始执行函数体代码

    此时当前函数的栈的内存布局如下:

  9. 恢复寄存器环境

  10. 释放分配的局部变量空间

    只是将当前的栈底指针(EBP)的值赋值给栈顶指针(ESP)就完成了:

  11. 恢复调用方栈底

  12. 平栈或者返回

    • 如果是_fastcall,_stdcall调用约定,那么被调用函数平栈后,取出返回地址

      函数流程转移到调用方

    • 其他调用约定则是直接取出保存的返回地址,函数流程返回到调用方,又调用方

      平栈

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,082
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,557
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,406
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,179
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,815
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,898