C语言函数调用完整过程

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;
        }
    函数参数参数传递:
    传递参数.png
    从上图中可以看出函数参数入栈
  2. 保存返回地址(紧挨着被调用函数的下一行可执行代码的内存地址)
    从上图中可以看出函数调用完成后,紧挨着的第一条指令为:
    00EB175B add esp,8
    所以,参数传递完成后就是返回值入栈:
    返回地址入栈.png
  3. 程序流程转移到被调用函数地址处
  4. 保存调用方栈底
    保存调用方栈底.png
  5. 切换到当前函数(被调用函数)的栈底
    调用方栈底保存完成后,当前的栈顶(ESP记录的地址)就成为被调用函数的栈底
    切换到被调用函数的栈底.png
  6. 为局部变量分配空间
    为局部变量分配空间.png
    这里程序为调试版本,所以为局部变量分配的空间比较大,在Release版本中
    会根据局部变量实际所需空间来分配大小
  7. 保存寄存器环境
    这里一共保存了3个寄存器,共12字节,在Release版本下,只保存两个
    保存寄存器环境.png
    在Debug版程序中(有/Zi(带有调试信息)和/Od(禁止优化)编译命令),除了为
    局部变量分配较大的内存空间外,还会将分配的局部变量空间全部置为0xCC:
    局部变量空间赋值CC.png
    这种填充方式比较直观,能够让我们在调试时直观的观察到是否发生越界等错误
  8. 开始执行函数体代码
    此时当前函数的栈的内存布局如下:
    当前函数堆桟布局.jpeg
  9. 恢复寄存器环境
    恢复寄存器环境.png
  10. 释放分配的局部变量空间
    只是将当前的栈底指针(EBP)的值赋值给栈顶指针(ESP)就完成了:
    释放局部变量空间.png
  11. 恢复调用方栈底
    恢复调用方栈底.png
  12. 平栈或者返回
    • 如果是_fastcall,_stdcall调用约定,那么被调用函数平栈后,取出返回地址
      函数流程转移到调用方
    • 其他调用约定则是直接取出保存的返回地址,函数流程返回到调用方,又调用方
      平栈

转载于:https://www.cnblogs.com/UnknowCodeMaker/p/11002225.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值