网站大量收购闲置独家精品文档,联系QQ:2885784924

C语言函数参数入栈的汇编理解汇编.docx

  1. 1、本文档共6页,可阅读全部内容。
  2. 2、有哪些信誉好的足球投注网站(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
C语言函数参数入栈的汇编理解汇编

先来看这样一段程序:[cpp]view plaincopyprint?#include?string.h??#include?stdlib.h??#include?stdio.h????void?print1(int?a,int?b,int?c)??{??????printf(%p\n,a);??????printf(%p\n,b);??????printf(%p\n,c);??}????int?main(void)??{?????print1(1,2,3);?????exit(0);??}??#include string.h#include stdlib.h#include stdio.hvoid print1(int a,int b,int c){ printf(%p\n,a); printf(%p\n,b); printf(%p\n,c);}int main(void){ print1(1,2,3); exit(0);}它的输出是:[cpp]view plaincopyprint?0022FF40??0022FF44??0022FF48??0022FF400022FF440022FF48发现a,b,c的地址是逐渐增大的,差值是4个字节。这和我所知道的:C函数参数入栈的顺序是从右到左是相匹配的,而且地址的增大值也与变量所占的字节数相匹配。不过当把程序稍微做一下修改,如下:[cpp]view plaincopyprint?#include?string.h??#include?stdlib.h??#include?stdio.h????void?print2(char?a,char?b,char?c)??{?????printf(%p\n,a);?????printf(%p\n,b);?????printf(%p\n,c);??}????int?main(void)??{?????print2(1,2,3);?????exit(0);??}??#include string.h#include stdlib.h#include stdio.hvoid print2(char a,char b,char c){ printf(%p\n,a); printf(%p\n,b); printf(%p\n,c);}int main(void){ print2(1,2,3); exit(0);}再观察一下它的输出:[cpp]view plaincopyprint?0022FF2C??0022FF28??0022FF24??0022FF2C0022FF280022FF24怎么和上面的效果是相反的!虽然我知道这肯定编译器的一个技巧,不过参数入栈的顺序是从右到左的概念却动摇了。为了弄清楚其中的道理,必须观察程序生成的中间.s文件,为此,我执行了以下一条命令:[cpp]view plaincopyprint?gcc?-S?test.c(当前C文件中保存的程序是文章一开始的那个)?在当前目录下生成test.s文件??gcc -S test.c(当前C文件中保存的程序是文章一开始的那个) 在当前目录下生成test.s文件使用vim打开test.s文件(只截取主要内容了):esp是指向栈顶的指针,ebp是用来备份这个指针的。栈的形状如下:espebp|____________________________________________________栈的最大值 ?? 栈的最小值每压入一个参数入栈,就执行 ?esp = esp - sizoeof(参数)。不过在esp值变之前,先备份一下ebp = esp,这样不管最后esp指到哪里去了,函数结束时就用这个ebp就能顺利回到调用者了。[cpp]view plaincopyprint?print1:?????pushl?%ebp//6.先把ebp压栈,保存这个指针?????movl??%esp,?%ebp//7.使ebp这个指针保存着esp这个指针指向的地址值?????subl??$8,?%esp//8.使esp?-?8,也就是说空下8个字节以便实现某个功能?????leal???8(%ebp),?%eax//9.把(ebp?+?8)的地址给eax?这个地方为什么要+8?因为这个函数在经历第5,6步的时候存在着压了两个4字节入栈的操作。此时+8就指向了实参1?????movl??%eax,?4(%esp)//10.这个时候就用到第8步空下来的8个字节中的4个了,原来是保存值,原理就是用C语言写两个数交换值时的那个第三个变量,即缓冲区?????movl??$.LC0,?(%esp)span?style=white-space:pre????/span//1

文档评论(0)

jiayou10 + 关注
实名认证
内容提供者

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

版权声明书
用户编号:8133070117000003

1亿VIP精品文档

相关文档