C语言函数调用完整过程
C语言函数调用详细过程
函数调用是步骤如下:
按照调用约定传参
调用约定是调用方(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;
}
函数参数参数传递:
从上图中可以看出函数参数入栈保存返回地址(紧挨着被调用函数的下一行可执行代码的内存地址)
从上图中可以看出函数调用完成后,紧挨着的第一条指令为:
00EB175B add esp,8
所以,参数传递完成后就是返回值入栈:
程序流程转移到被调用函数地址处
保存调用方栈底
切换到当前函数(被调用函数)的栈底
调用方栈底保存完成后,当前的栈顶(ESP记录的地址)就成为被调用函数的栈底
为局部变量分配空间
这里程序为调试版本,所以为局部变量分配的空间比较大,在Release版本中
会根据局部变量实际所需空间来分配大小保存寄存器环境
这里一共保存了3个寄存器,共12字节,在Release版本下,只保存两个
在Debug版程序中(有/Zi(带有调试信息)和/Od(禁止优化)编译命令),除了为
局部变量分配较大的内存空间外,还会将分配的局部变量空间全部置为0xCC:
这种填充方式比较直观,能够让我们在调试时直观的观察到是否发生越界等错误开始执行函数体代码
此时当前函数的栈的内存布局如下:
恢复寄存器环境
释放分配的局部变量空间
只是将当前的栈底指针(EBP)的值赋值给栈顶指针(ESP)就完成了:
恢复调用方栈底
平栈或者返回
- 如果是_fastcall,_stdcall调用约定,那么被调用函数平栈后,取出返回地址
函数流程转移到调用方 - 其他调用约定则是直接取出保存的返回地址,函数流程返回到调用方,又调用方
平栈
- 如果是_fastcall,_stdcall调用约定,那么被调用函数平栈后,取出返回地址
C语言函数调用完整过程的更多相关文章
- C语言函数调用过程,汇编角度查看
C语言函数调用过程,汇编角度查看 把函数的参数按照调用约定压栈或者存储到寄存器中 调用要使用的函数,先把调用者的地址入栈,方便回来 跳转到函数 把函数使用到的一些寄存器压栈,避免修改寄存器的值 执行函 ...
- C语言函数调用时候内存中栈的动态变化详细分析(彩图)
版权声明:本文为博主原创文章,未经博主允许不得转载.欢迎联系我qq2488890051 https://blog.csdn.net/kangkanglhb88008/article/details/8 ...
- 字符型图片验证码识别完整过程及Python实现
字符型图片验证码识别完整过程及Python实现 1 摘要 验证码是目前互联网上非常常见也是非常重要的一个事物,充当着很多系统的 防火墙 功能,但是随时OCR技术的发展,验证码暴露出来的安全问题也越 ...
- 测试c语言函数调用性能因素之测试三
函数调用:即调用函数调用被调用函数,调用函数压栈,被调用函数执行,调用函数出栈,调用函数继续执行的一个看似简单的过程,系统底层却做了大量操作. 操作: 1, 调用函数帧指针 ...
- Django之model模块创建表完整过程
Django中,与数据库相关的模块是model模块,它提供了一种简单易操作的API方式与数据库交互,它是通过ORM映射的方式来操作数据库,一个类对应数据库一张表,一个类属性,对应该表的一个字段,一个实 ...
- UIPickerView/UIDatePicker/程序启动的完整过程
一.UIPickerView 1.UIPickerView的常见属性 数据源(用来告诉UIPickerView有多少列多少行) @property(nonatomic,assign) id<UI ...
- C语言函数调用栈
C语言函数调用栈 栈溢出(stack overflow)是最常见的二进制漏洞,在介绍栈溢出之前,我们首先需要了解函数调用栈. 函数调用栈是一块连续的用来保存函数运行状态的内存区域,调用函数(calle ...
- StartSSL免费SSL证书申请和账户注册完整过程
StartSSL算是比较早提供免费SSL证书的第三方提供商,我们可以免费申请且免费续期使用到有需要HTTPS网址的用户.关于网站使用SSL证书主要还是因为谷歌在向导说明中提到如果一个网站使用到SSL证 ...
- C语言的编译过程、安装gcc编译器以及设置环境变量
以我对C语言编译过程的了解,我用了一点时间画了一个图,提供给大家参考一下,希望有些能对您的问题提上帮助. 前几天刚初步学习了C语言的编译过程,感触挺深的.在C语言中头文件其实起了一个很大的作用. 1. ...
随机推荐
- js 十大排序算法 All In One
js 十大排序算法 All In One 快速排序 归并排序 选择排序 插入排序 冒泡排序 希尔排序 桶排序 堆排序(二叉树排序) 基数排序 计数排序 堆排序(二叉树排序) https://www.c ...
- 编程术语 All In One
编程术语 All In One js 名词,术语 函数 函数签名 一个函数签名 (或类型签名,或方法签名) 定义了 函数 或 方法 的输入与输出. 一个签名可以包括: 参数 及参数的 类型 一个返回值 ...
- DNS & TXT recode & Google Search Console
DNS & TXT recode & Google Search Console domain name verification / 域名验证 demo DNS TXT recode ...
- 「NGK每日快讯」2021.1.26日NGK公链第84期官方快讯!
- 微信附近的人,用redis也能实现?(GEO)
相信微信附近的人的功能大家都应该用过 我可以很随意的通过我自己的定位能看到我附近的人,并且能看到那个人距离我的距离,大家有没有思考过这个是怎么实现的? 作为一个程序猿任何问题应该都有一个思考的过程,而 ...
- SSL/TLS协议详解(中)——证书颁发机构
本文转载自SSL/TLS协议详解(中)--证书颁发机构 导语 上一篇中,我们讨论了关于Diffie Hellman算法的SSL/TLS密钥交换.我们最终认为需要第三方来验证服务器的真实性,并提出了证书 ...
- MySQL -- 内部临时表
本文转载自MySQL -- 内部临时表 UNION UNION语义:取两个子查询结果的并集,重复的行只保留一行 表初始化 CREATE TABLE t1(id INT PRIMARY KEY, a I ...
- 导入Excel时,如果有多个投料信息,则循环导入
List<Input> list = new ArrayList<Input>();for (int j = 0; j < 500; ) { String materia ...
- Ctf_show Web[1-8]
CTFshow_web1: F12查看JS即在代码里 CTFshow_web2: 进入网址后页面如下: ①:尝试使用admin登陆,发现页面无回显 ②:尝试单引号闭合,并且添加' or 1=1#,此时 ...
- 搭载华为麒麟9000的Mate X2:秒售罄,一机难求
本文首发 | 公众号:lunvey 昨日10点,搭载了麒麟9000芯片的华为Mate X2正式开售,定价17999,对于手机来说,价格实在是高昂. 虽然价格高昂,但是一分钱一分货,对于想抢先体验的网友 ...