- 1、本文档共6页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 5、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 6、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 7、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 8、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
C语言函数调用与底层机制
这是一篇介绍C语言中的函数调用是如何用实现的文章。写给那些对C语言各种行为的底层实现感兴趣人的入门级文章。如果你是C语言或者汇编、底层技术的老鸟或是对这个问题不感兴趣,那么这篇文章只会耽误您的时间,您大可不必阅读他。当然如果前辈们愿意为我指出不足,我将十分感谢您的指导,并对耽误您宝贵的时间致歉。好了,废话少说!要研究这个问题,让我们先打开VC++吧。最好是6.0的,:-P。(什么你没有VC++,倒!....赶快装一个!@#$,要快!)首先,让我们在VC++里建立一个Win32 Console Application项目,并建立主文件fun.c。并输入以下内容。
int fun(int a, int b) { a = 0x4455; b = 0x6677; return a + b;}int main() { fun(0x8899,0x1100); return 0;}
之后,最关键的是在项目设置里关闭优化功能。也就是把Project-Setting-C/C++-Optimizations选为Disabled。编译器的优化在分析底层实现时大多数情况不太受欢迎。 按键盘上的F10键,进入单步调试模式(StepOver)。看到你的main函数左侧有个黄色的小箭头了吗?那个就是程序即将执行的语句。按Alt +8。打开反编译窗口,看到汇编语句了吗?是不是想这个样子
== push 1100h 0040107D push 8899h call @ILT+5(fun) (0040100a) add esp,8
看到两个PUSH指令了吗?再看看后面的数字,不正是我们要传递的参数吗。奇怪阿?我们明明是先传递的0x8899怎么反倒先push1100h呢?呵呵,这个现象就叫Callingconversion。究竟是何方神圣,我在后面会详细的给你解释的。先别着急。随后的Call指令的作用就是开始调用函数了。接下来关掉反汇编窗口,在源代码窗口按F11(StepInto)进入函数体。当看到那个黄色的小箭头指向函数名的时候再调出反汇编窗口(Alt+8)。你会看到类似下面的代码:
1: int fun(int a, int b) { push ebp mov ebp,esp sub esp,40h push ebx push esi push edi lea edi,[ebp-40h]0040100C mov ecx,10h mov eax,0CCCCCCCCh rep stos dword ptr [edi]2: a = 0x4455; mov dword ptr [ebp+8],4455h3: b = 0x6677;0040101F mov dword ptr [ebp+0Ch],6677h4: return a + b; mov eax,dword ptr [ebp+8] add eax,dword ptr [ebp+0Ch]5: }0040102C pop edi0040102D pop esi0040102E pop ebx0040102F mov esp,ebp pop ebp ret
VC++就是好,还在难懂的汇编语句前加入了C语言的源代码。不过同时也有不少我们不需要的代码。因此,你只需要关心红色的部分就可以了。奇怪阿?不是参数都用push传递了吗?怎么没看到被pop出来?问题其实是这样,当你调用Call进入函数的时候Call背着你做了一件事。call把它下一条语句的地址push进了堆栈。(旁人:什么!这是为什么?)原因很简单,因为函数调用完了,要用ret返回。而ret怎么知道返回哪里呢?对了,ret指令pop了call指令pus
您可能关注的文档
- 2015年二级建造师考试试题与答案解析《市政实务》完整版4.doc
- 2015年注册安全工程师生产技术全真模拟试题与答案解析.doc
- 2015年湖南省普法读本练习题一判断题与答案.doc
- 2015江苏高考政治试题与答案.doc
- 2015电大土木工程【钢结构】形成考核册与答案带题目.doc
- 2015年高考地理试题与答案word校正后.doc
- 2012全国各省地理高考题与答案汇编2.doc
- 2016一建建筑-真题与解析-打印.doc
- 2016一级建造师考试《建筑工程》精选习题与答案解析.doc
- 2016年北京电影学院管理系影视制片管理参考书与笔记分享.doc
- 2025年金肯职业技术学院单招职业适应性测试题库带答案.docx
- 2025年钦州幼儿师范高等专科学校单招综合素质考试题库完美版.docx
- 2025年钟山职业技术学院单招职业适应性考试题库参考答案.docx
- 2025年金华职业技术学院单招职业技能测试题库附答案.docx
- 2025年闽南理工学院单招职业技能测试题库审定版.docx
- 2025年闽南理工学院单招综合素质考试题库审定版.docx
- 2025年闽南理工学院单招职业倾向性考试题库汇编.docx
- 2025年闽南理工学院单招职业倾向性考试题库推荐.docx
- 2025年闽北职业技术学院单招综合素质考试题库1套.docx
- 2025年长沙轨道交通职业学院单招职业技能考试题库一套.docx
文档评论(0)