函数简介及调用过程实现原理
函数
关键词:function name 函数名 param 参数 return 返回值
优点:代码重用(软件的可维护性。高内聚,低耦合)
软件的可维护性:易发现问题好改。
强内聚:一个软件的模块是由相关性很强的代码组成,只负责一项任务,也就是常说的单一原则。
低耦合:一个完整的系统,模块与模块之间,尽可能的使其独立存在。
缺点:降低运行速度,性能换内存。
为了避免多次使用和修改,所以定义函数方便存取。
Void 自定义函数名 (自定义函数类型和数量) //比如 void hs(int i,int j)
{
主结构
}
调用时: 文件前声明
Void 自定义函数名(void)
然后使用: 自定义函数名();
Void 自定义函数名 (自定义函数类型和数量)中的 自定义函数类型和数量 叫做形参
自定义函数名(); 括号里的常数为 实参
返回值
return 的作用是结束正在运行的函数,并返回函数值。return后面可以跟一个常量,变量,或是表达式。
比如:
float area (float r)
{
return 3.14 * r * r ;
}
调用时 : result = area(2); //结果就是圆的面积
函数内存实现的原理
1. 调用约定参数
调用方(caller)和被调用方(callee)需要约定以下内容
1. 传参顺序
2. 传递参数的媒介
3. 清理参数的责任归属
4. 返回值的传递媒介
2. 保存返回值地址
3. 保存调用方的栈底
4. 设置当前栈顶为被调用方的栈底(此时被调用方属于空栈)
5. 根据局部变量所需要的总空间,太高栈顶(为局部变量分配空间)
6. 保存处理环境(把调用方的处理器的值赋给栈顶)
7. Debug选项组设置局部变量的初始值为0xcccccccc(方便调试错误)
8. 执行函数体
9. 恢复处理器环境(把栈顶的值复制到处理器中)
10. 释放局部变量空间
11. 从栈顶取值恢复到调用方的栈底
12. 从栈顶取值作为返回地址(_stdcall和_fastcall此时释放空间)
13. 流程恢复到调用方的代码(_cdecl此时释放空间)
Foo |
Save cpu vale |
Top |
|
Local |
|
|
Main stack base(main栈底) |
Base |
|
恢复地址 |
|
|
1(从右往左最后一个参数) |
|
|
2 |
|
|
3(从右往左第一个参数) |
|
|
Main |
首先我们写一个函数
初始的内存结构
通过调试会在空间申请main函数的栈空间
通过找参数一的值 01 00 00 00找到main函数入口
我们先传一个简单的参数进去 说错了,不是环境变量是处理器环境。
局部变量的初始值为0xcccccccc 方便调试
下面我们开始return这个函数
将流程恢复到调用方代码