C&C++
发布时间:2022-04-13 发布网站:大佬教程 code.js-code.com
大佬教程收集整理的这篇文章主要介绍了C-05\函数的底层原理,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
一、程序运行时内存四大区
wres
(内存属性):
- w:
write
(可写)@H_696_10@
- r:
read
(可读)@H_696_10@
- e:
execute
(可执行)@H_696_10@
- s:
share
(可共享)@H_696_10@
任何操作系统(windows、liunx
、安卓、ios
等)上的程序在运行时,都有内存四大区,分别为:代码区(codE),数据区(data),栈区(stack),堆区(heap)
代码区(codE):存放二进制可执行代码,内存属性为re
数据区(data):存放全局变量,静态变量和常量(C语言)
栈区(stack):先进后出,后进先出(类似弹夹),内存属性为rw
。经常被翻译为堆栈,其实就是栈区,这是老一辈翻译国外技术书籍时候的一个习惯,喜欢成对成对的用词,而中国传统习惯是后者定性,例:礼无可恕,情有可原。那么你就被放了,没事。如果说 情有可原,礼无可恕,那么你就摊上大事了。再例:牛奶,是奶;奶牛,是牛。所以指针数组是数组,数组指针是指针
堆区(heap):内存属性为rw
二、函数的底层原理
每个函数都有一个属于自己的栈空间,用来记录函数的必要信息
- 按调用约定传参
- 参数的传递方向(是从右向左还是从左向右传参)@H_696_10@
- 参数的存储媒介(参数放寄存器还是栈区或者其他)@H_696_10@
- 谁负责释放(平衡)参数空间@H_696_10@
- 返回值的处理@H_696_10@
@H_696_10@
|
__cdecl |
__stdcall |
__fastcall |
解释 |
C调用约定,美国国标标准,默认调用约定 |
标准约定,微软的规定,微软操作系统使用的调用规定,Windows API 的标准调用约定 |
快速约定,只有微软某一系列编译器独有的,未标准化,不同编译器可能没有或者实现不一致 |
参数传递方式 |
从右往左,通过栈传递 |
从右往左,通过栈传递 |
左数前两个参数放在ecx 、edx 寄存器中,其余从右往左通过栈传递 |
谁清理栈上参数 |
调用者(caller) |
被调者(calleE) |
被调者(calleE) |
编译器参数 |
/Gd |
/Gz |
/Gr |
可变参 |
支持 |
不支持 |
不支持 |
@H_616_176@
-
在栈顶保存返回地址
@H_696_10@
-
保存调用方的栈信息(调用方的栈底位置)
@H_696_10@
-
更新栈位置(在处理器里)到被调用方的栈底处
@H_696_10@
-
在栈内开辟局部变量的空间
编译器此时会统计局部变量的大小(占多大空间),然后以此开辟足够空间
调试版开辟的空间大于等于实际局部变量的大小,发行版(优化版)开辟的空间小于等于实际局部变量的大小
@H_311_197@ 使用`/O1`和`/O2`编译选项会根据变量使用情况,会分配小于等于变量大小的空间,例:
@H_311_197@// 第一种优化情况
// 如果开了优化,编译器不会给局部变量nNum开辟空间
// 而是直接使用 printf("%d",3);
int nNum = 3;
printf("%d",nNum)
// 第二种优化情况
// 根据情况使用寄存器存储变量
编译选项有/Zi+/Od
(调试版且不优化),则填充局部变量空间为0xcc
@H_696_10@
-
保存寄存器环境
@H_696_10@
-
执行函数体
@H_696_10@
-
恢复寄存器环境
@H_696_10@
-
释放局部变量空间
@H_696_10@
-
恢复栈信息到调用方
@H_696_10@
-
如果是 __cdecl
,先取出返回地址,并按此返回地址作流程更新,抵达新地址后,由调用方清理参数;
如果是 __fastcall,__stdcall
,先取出返回地址,并清理参数,然后按返回地址作流程更新
@H_696_10@
三、函数的递归调用
递归善于处理非线性问题,不善于处理线性问题,循环善于解决线性问题
- 线性问题:有唯一的前驱且有唯一的后继的问题,例:n的累加@H_696_10@
- 非线性问题:A问题产生分支,产生了
B1
问题和B2
问题,B1
与B2
合并产生C问题,C问题又回归到A问题@H_696_10@
四、函数注释规范
- 函数功能@H_696_10@
- 各个参数意义@H_696_10@
- 返回值意义(void写无,不能不写)@H_696_10@
- 备注或其他信息@H_696_10@
- 版本和修改日期,修改人(看公司需要)@H_696_10@
五、附加知识
Alt+F8
(VC++6.0
代码对齐快捷键)@H_696_10@
- 函数可以通过提供.obj文件或动态链接库给别人使用@H_696_10@
- 裸函数不属于调用约定,是一个关键字,让编译器不为此函数生成任何代码的关键字@H_696_10@
- Fibonacci数列可求黄金分割比例,越后面的前一项和后一项的比值越接近0.618@H_696_10@
- 函数名前加
_
表示内层函数@H_696_10@
大佬总结
以上是大佬教程为你收集整理的C-05\函数的底层原理全部内容,希望文章能够帮你解决C-05\函数的底层原理所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。
标签: