CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
IBM Rational 系统开发最佳实践工具包 WebSphere MQ 最佳实践 TOP 15
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  C/C++ >  C语言

请教c/c++函数的压栈顺序。

楼主bulala()2006-03-15 10:49:30 在 C/C++ / C语言 提问

比方说   int   test(int   a,   int   b,   int   c){  
                  int   z;  
                  return   1;  
  }  
  这个函数如何压入栈中〉?  
  请作图。包括ebp和ret 问题点数:20、回复次数:10Top

1 楼songsong33(天堂里的蚊子)回复于 2006-03-15 11:22:23 得分 0

把函数压入栈是第一次看到也,能不能让函数指针进栈来实现?Top

2 楼wu19821214(狗)回复于 2006-03-15 12:00:43 得分 0

用汇编用push,哈哈Top

3 楼jixingzhong(瞌睡虫·星辰)回复于 2006-03-15 12:26:04 得分 20

函数参数入栈可以控制的   ~Top

4 楼jixingzhong(瞌睡虫·星辰)回复于 2006-03-15 12:27:32 得分 0

刚看到的帖子内容   :  
   
  duduhaha(三人行必有我师)   (   )   信誉:100     2006-3-14   21:32:09     得分:   0      
   
  看看下面的.  
  函数调用约定有多种,这里简单说一下:  
  1、__stdcall调用约定相当于16位动态库中经常使用的PASCAL调用约定。在32位的VC++5.0中PASCAL调用约定不再被支持(实际上它已被定义为__stdcall。除了__pascal外,__fortran和__syscall也不被支持),取而代之的是__stdcall调用约定。两者实质上是一致的,即函数的参数自右向左通过栈传递,被调用的函数在返回前清理传送参数的内存栈,但不同的是函数名的修饰部分(关于函数名的修饰部分在后面将详细说明)。  
  _stdcall是Pascal程序的缺省调用方式,通常用于Win32   Api中,函数采用从右到左的压栈方式,自己在退出时清空堆栈。VC将函数编译后会在函数名前面加上下划线前缀,在函数名后加上"@"和参数的字节数。  
  2、C调用约定(即用__cdecl关键字说明)按从右至左的顺序压参数入栈,由调用者把参数弹出栈。对于传送参数的内存栈是由调用者来维护的(正因为如此,实现可变参数的函数只能使用该调用约定)。另外,在函数名修饰约定方面也有所不同。  
  _cdecl是C和C++程序的缺省调用方式。每一个调用它的函数都包含清空堆栈的代码,所以产生的可执行文件大小会比调用_stdcall函数的大。函数采用从右到左的压栈方式。VC将函数编译后会在函数名前面加上下划线前缀。是MFC缺省调用约定。  
  3、__fastcall调用约定是"人"如其名,它的主要特点就是快,因为它是通过寄存器来传送参数的(实际上,它用ECX和EDX传送前两个双字(DWORD)或更小的参数,剩下的参数仍旧自右向左压栈传送,被调用的函数在返回前清理传送参数的内存栈),在函数名修饰约定方面,它和前两者均不同。  
  _fastcall方式的函数采用寄存器传递参数,VC将函数编译后会在函数名前面加上"@"前缀,在函数名后加上"@"和参数的字节数。    
  4、thiscall仅仅应用于"C++"成员函数。this指针存放于CX寄存器,参数从右到左压。thiscall不是关键词,因此不能被程序员指定。  
  5、naked   call采用1-4的调用约定时,如果必要的话,进入函数时编译器会产生代码来保存ESI,EDI,EBX,EBP寄存器,退出函数时则产生代码恢复这些寄存器的内容。  
  naked   call不产生这样的代码。naked   call不是类型修饰符,故必须和_declspec共同使用。  
  关键字   __stdcall、__cdecl和__fastcall可以直接加在要输出的函数前,也可以在编译环境的Setting...\C/C++   \Code   Generation项选择。当加在输出函数前的关键字与编译环境中的选择不同时,直接加在输出函数前的关键字有效。它们对应的命令行参数分别为/Gz、/Gd和/Gr。缺省状态为/Gd,即__cdecl。  
  要完全模仿PASCAL调用约定首先必须使用__stdcall调用约定,至于函数名修饰约定,可以通过其它方法模仿。还有一个值得一提的是WINAPI宏,Windows.h支持该宏,它可以将出函数翻译成适当的调用约定,在WIN32中,它被定义为__stdcall。使用WINAPI宏可以创建自己的APIs  
   
   
       
     
  Top

5 楼bulala()回复于 2006-03-15 17:45:12 得分 0

我的意思是:此函数延展后stack的图:谁能给我画出来。Top

6 楼songsong33(天堂里的蚊子)回复于 2006-03-15 19:44:34 得分 0

晕了:)不知道楼主的意思,关注!Top

7 楼DelphiGuy()回复于 2006-03-15 20:46:30 得分 0

Borland编译器的__fastcall和ms定义的不一样,它用了三个寄存器传递左起的参数:EAX、EDX、ECX。  
  Top

8 楼tb01412(tb)回复于 2006-03-15 21:57:56 得分 0

不同的编译器对参数的入栈顺序有可能不一样的Top

9 楼Acoolice()回复于 2006-03-16 10:35:15 得分 0

不明白楼主什么意思!关注!Top

10 楼bulala()回复于 2006-03-16 10:38:01 得分 0

我de意思是:  
   
  cdecl时  
  内存低地址             内存高地址  
      ret   ebp   z   a   b   c  
  栈顶   《--------栈底  
  这样的分布是正确的马?Top

相关问题

  • c++函数
  • C函数
  • c语言中的字节顺序转换函数在java中怎么实现?
  • 函数的执行顺序
  • C++函数手册!
  • 求C#的函数?
  • 再求函数(C#)?
  • C++入口函数
  • 求一C#函数
  • C/C++的函数问题

关键词

  • c/c++
  • 函数
  • 编译
  • 编译器
  • 内存
  • 代码
  • pascal
  • 调用约定
  • 参数
  • 入栈

得分解答快速导航

  • 帖主:bulala
  • jixingzhong

相关链接

  • C/C++ Blog
  • C/C++类图书
  • C/C++类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo