调用函数时,函数参数是如何压栈的?

booirror 2012-06-25 09:13:31
例如:foo(int a,int b,int c);
函数参数是如何压栈的?各参数变量在内存中的地址大小关系如何?为什么?
...全文
776 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2012-06-26
  • 打赏
  • 举报
回复
VC调试(TC或BC用TD调试)时按Alt+8、Alt+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。
对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。
(Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)

提醒:
“学习用汇编语言写程序”

“VC调试(TC或BC用TD调试)时按Alt+8、Alt+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。
(Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)”
不是一回事!

不要迷信书、考题、老师、回帖;
要迷信CPU、编译器、调试器、运行结果。
并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。
任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实!
mc913 2012-06-26
  • 打赏
  • 举报
回复
参数入栈,由编译器决定,看下汇编语言,就知道参数是怎么入栈的。
AnYidan 2012-06-26
  • 打赏
  • 举报
回复
5 楼解释的很清楚,

一般的程序员不需要很清楚这些,只要知道 1 楼的答案错误即可

就象老板发薪水给你,他不关心你如何消费
zyb_debug 2012-06-26
  • 打赏
  • 举报
回复
__stdcall __cdecl
一般情况下 这两个还经常见 其他的调用方式很少见了(或许是我水平有限,本来就间的不多)
pathuang68 2012-06-26
  • 打赏
  • 举报
回复
pathuang68 2012-06-26
  • 打赏
  • 举报
回复
一共有5中函数调用约定(calling convention),它决定一下内容:

1) 函数参数的压栈顺序

2) 由调用者还是被调用者把参数弹出栈

3) 产生函数修饰名的方法



__stdcall调用约定:

函数的参数自右向左通过栈传递,被调用的函数在返回前清理传送参数的内存栈,



__cdecl调用约定:

是C和C++程序的缺省调用方式。每一个调用它的函数都包含清空堆栈的代码,所以产生的可执行文件大小会比调用__stdcall函数的大。函数采用从右到左的压栈方式。注意:对于可变参数的成员函数,始终使用__cdecl的转换方式。



__fastcall调用约定:

它是通过寄存器来传送参数的(实际上,它用ECX和EDX传送前两个双字(DWORD)或更小的参数,剩下的参数仍旧自右向左压栈传送,被调用的函数在返回前清理传送参数的内存栈)。



thiscall调用约定:

仅仅应用于"C++"成员函数。this指针存放于CX寄存器,参数从右到左压。thiscall不是关键词,因此不能被程序员指定。



naked call调用约定:

采用上述4种调用约定时,如果必要的话,进入函数时编译器会产生代码来保存ESI,EDI,EBX,EBP寄存器,退出函数时则产生代码恢复这些寄存器的内容。naked call不产生这样的代码。naked call不是类型修饰符,故必须和_declspec共同使用。



关键字 __stdcall、__cdecl 和 __fastcall 可以直接加在要输出的函数前,也可以在编译环境的 Setting...\C/C++ \Code Generation 项选择。当加在输出函数前的关键字与编译环境中的选择不同时,直接加在输出函数前的关键字有效。它们对应的命令行参数分别为/Gz、/Gd 和 /Gr。缺省状态为/Gd,即__cdecl。缺省状态为__cdecl。
quwei197874 2012-06-25
  • 打赏
  • 举报
回复
google c语言四种函数调用约定
Athenacle_ 2012-06-25
  • 打赏
  • 举报
回复
stdcall 从右到左
cdecl 从右到左
fastcall一般不入栈
Arnold9009 2012-06-25
  • 打赏
  • 举报
回复
参数从右到左入栈
具体地址大小关系要看堆栈是向内存哪个方向增长,一般来说,最后入栈的地址最小
图灵狗 2012-06-25
  • 打赏
  • 举报
回复
C语言压栈的顺序时从右向左进行压栈,即先压入c,其次是b,最后是a。

69,381

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧