【技术研究】函数调用,栈细节

TEC

Posted by Corax on November 5, 2023

ascii源于电报

换行 \r 本来是纸张前移,x轴不变,y加一

回车 \n 针脚复位,x轴归零,y不变

PC中,不同编译环境不同操作系统对\n有不同理解

​ 微软的回车 列清零 行加一 等于以前融合的\r\n

​ 仍然有些系统沿用电报系统

函数调用

函数解决问题 解决问题依赖关系 后进先出

​ 有点像递归的解决路线

计算机结构 栈结构

每个函数有独立栈环境,不同栈环境的变量相互隔离

image-20231106150020585

通常还要表上零地址的位置,如下图不停压栈的时候作减法,调用方和被调用方需要确定栈结构生长方向,属于体系结构问题。

image-20231106150216923

实际上这些地方都是有参数空间的

image-20231106160020715image-20231106174544096

  1. 按调用约定传递参数 调用约定 需要调用方caller和被调方callee作出以下约定: 参数的传递方向 从左往右 从右往左 参数的传递媒介 用栈传递 寄存器传递 函数值返回的位置 栈 寄存器 释放参数空间的负责方 有且仅有一方可以释放参数空间

  2. 保存返回地址

  3. 保存调用方栈信息 esp?栈帧? 栈底比较好访问栈内信息,所以保存的是栈底

  4. 更新当前栈顶到栈底

    把当前栈顶作为被调方的栈底

  5. 为局部变量申请空间 抬高栈顶 调试的时候,一般都是给足栈空间,通常大于所有局部变量等之和。 发布版的时候,一般会小于之和,编译器会做一些优化,例如变量复用等等操作

  6. 保存寄存器环境 把即将使用的寄存器原值保存在栈中(其实就三个,一共八个寄存器,三个参数传递不用,两个栈寄存器。) 调试版全保存,发布版保存需要的

  7. 如果编译器有/ZI /Zi等调试选项的 局部变量初始化为0xcccccccc

  8. 执行函数体

  9. 要出来了 恢复寄存器环境

  10. 释放局部变量的空间 调动栈顶指针

  11. 恢复调用方的栈信息

  12. cdecl约定,取出当前栈顶作为返回的流程地址,返回调用方后,由调用方清理参数空间。 其他约定,取出当前栈顶作为返回的流程地址,再由被调方清理参数空间后才返回

递归中,函数返回地址都相同,一眼可以在栈中间看出来

  1. C约定_cdecl 参数使用栈传递,从右往左,返回值在寄存器,caller负责释放
  2. 标准库约定_stdcall 栈传递 右往左 寄存器 callee释放
  3. _fastcall 左数前两个寄存器传 其他栈传递 右往左 返回在寄存器 callee释放 微软独有

此处和编译器选项描述调用约定

image-20231106153114878

image-20231106153243556

来找一个程序试试

#include "stdafx.h"
#include <iostream>
#include <stdio.h>
using namespace std;

int sum(int m, int n)
{
    int sum1 = n + m;
    return sum1;
}

int main(int argc, char* argv[])
{
	int n=1;
    int i=0;
    for (i=0;i<9;i++)
    {
        n=n+1;
        n=n*2;
    }
    printf("%d\r\n",n);
    int m = 5;
    int p = 6;
    int c = sum(m,p);
    printf("%d\r\n",c);
    system("pause");
	return 0;
}

下断点下这里

image-20231106165619853

观测到内存空间里

下面就是调用main的时候栈做的一些操作

利用的

image-20231106170049925

1 1 命令行个数 整型

1 2 命令行列表 字符型指针数组

1 3 环境变量列表 字符型指针数组

2 main函数返回地址

3 调用方栈信息 同时此处作为main函数的栈底

4 main函数局部空间

5 三个dword 寄存器环境

然后根据一下走到sum函数里面会是咋样

00000006 00000005 0040130D 0019FF30 很多CC 然后三个dword

40130D根据这里来,是call后面要返回的位置

image-20231106171447406

0019FF30 就是这里,main函数的栈底

image-20231106171523306

分区

data 全局变量静态变量 常量

image-20231106171916191