c函数调用和参数传递机制的探讨.docVIP

  1. 1、本文档共10页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  5. 5、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  6. 6、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  7. 7、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  8. 8、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
c函数调用和参数传递机制的探讨

关于C语言中函数调用和参数传递机制的探讨 函数,相信许多人也知道其重要性;一个文件往往由一个或者多个函数构成的。然而可能许多人还不知道函数调用的一些深层问题,所以我写的这篇文章一来是应 了一个好朋友的要求而写,二来希望一些朋友能够从我这篇文章了解函数调用的机制。但是并不是每个人都可以完全读懂这文章,想完全读懂此文,我想必须具备三个条件: 一、对于C语言有一定的了解,最起码有一个整体的初步了解; 二、能够读懂UNIX/LINUX下的AT&T语法的汇编;AT&T汇编与Intel汇编的差别还是挺大的;这个条件可能一些人就不具备了,但是你通过阅读此文相信也能对函数调用机制有一个大概的了解; 三、看到这么长的文章,一定要有耐心,用心看相信应该多少有点帮助; 好了,不讲废话了,进入主题吧。 一、基本知识框架了解: 这部分主要讲一些基本的东西,主要是关于堆栈的知识。只有了解了堆栈的基础内容,才可以继续往下读。 1.概念性的知识: 所谓堆栈,其实也就是程序使用的一种内存元素;它是内存中用来存放一些数据的区域。我曾经写过一篇文章发表在这个论坛上里面也谈到了堆和栈的区别;平常经常说的堆栈,其实也是栈,而不是堆,所以这里也一样。注意这和数据结构说的栈其实还是有区别的,不要混在一起。 2.堆栈的工作方式: 平常我们所说的数据是怎么存放在内存的?是从低地址开始,然后按照数据占用字节大小往高地址逐个存放的。但堆栈就不一样了。堆栈的工作方式是数据插入堆栈区域然后从堆栈区域删除数据。这是概括的说法。具体是这样的: 在UNIX/LINUX中,堆栈是从高地址向低地址衍生的。这里得说一个重要的东东,那就是堆栈指针ESP。堆栈指针是什么?它永远指向堆栈中的顶部(但如果按照地址值来说却是底部),是不是对顶部这个词的理解感觉有点模糊?就是说,比如说你压栈,就压进一个4字节的数据元素,那么ESP就向下移动了4个字节,注意这里是向下移动,所以ESP应该指向了更低的地址,所以说它是指向了底部。你可以把堆栈想象成一个杯子,倒进水了水平线是不是上升了(这里把杯子最底端假设成高地址,把顶端设为低地址),倒出水了水平线是不是下降了?就和压栈和进栈的道理一样的。如果还没有理解也没关系,自己画个图仔细比较就可以了。这里让我偷懒一下就不画图了。 3.压栈和进栈指令简介: 压栈指令 : pushx source 其中, x可以是 w(表示字), 或者是l(表示长字);source可以是数值或者寄存器值或者内存地址; 出栈指令 : popx des 同样,x可以是 w(表示字), 或者是l(表示长字);des可以是寄存器值或内存值; 关于最最基本的东西已经讲得差不多了,当然还有其他一些基本东西,留给大家去查资料了,这部分讲的都和本文有密切关系的东西。 二、函数如何通过堆栈来解决问题: 这部分是对函数如何通过堆栈解决函数调用以及参数传递的理论性理解,相当重要,只有了解之后才可以进行实例的分析,这一大部分同样分成几个小部分: 1.通过堆栈操作实现参数的传递: 前面说过,堆栈的基本操作可以是压栈和出栈,而参数的传递就是通过这种方式来实现的。ESP永远指向了堆栈顶部,如果这时候压进一个int型的数据元素,那么ESP向下移动了4个字节,这时候它还是指向了堆栈的顶部(注意了,顶部的地址比移动前的地址低,不要乱了)。假如把一个int型数据元素出栈,那么ESP向上移动4个字节,这时候它还是指向了堆栈的顶部,只是现在地址是增加了4个字节。所以,如果一个函数需要传递参数过去那么就得在调用函数之前先把参数压进栈,然后再调用。关于这点后面我会详细说一下,现在你如果没理解也没关系。 2.函数调用的一般汇编指令: 函数调用的一般汇编指令都是那么几条,下面我把他们按一般顺序罗列出来: #Asm Code function: pushl %ebp movl %esp, %ebp subl $8, %esp #... movl %ebp, %esp popl %ebp ret 下面先简单分析这几句一般汇编指令的意思和目的。 pushl %ebp #这句把寄存器%ebp压栈,目的是什么呢?看下一条指令: movl %esp, %ebp #把寄存器%esp的值给

文档评论(0)

wannian118 + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档