社区
C语言
帖子详情
调用函数时,函数参数是如何压栈的?
booirror
2012-06-25 09:13:31
例如:foo(int a,int b,int c);
函数参数是如何压栈的?各参数变量在内存中的地址大小关系如何?为什么?
...全文
799
10
打赏
收藏
调用函数时,函数参数是如何压栈的?
例如:foo(int a,int b,int c); 函数参数是如何压栈的?各参数变量在内存中的地址大小关系如何?为什么?
复制链接
扫一扫
分享
转发到动态
举报
AI
作业
写回复
配置赞助广告
用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
打赏
举报
回复
参考:
CALLBACK, WINAPI, AFXAPI和函数调用方式
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。
【C语言】函数调用的参数
压栈
(详解)
文章目录前言1.什么是栈区?1.1栈区小知识点2.知识点2.1 寄存器2.2 主函数调用3. 逐条解释3.1 从main开始3.2 调用Add3.3 回到main函数3.4 结束程序4.本篇博客中的汇编语言总结5.结语 前言 在早期的学习中,我们已经了解到当函数传值调用参数的
时
候,用的是形参。 形参是实参的一份临
时
拷贝,对形参的改变不会影响实参里的值。 传值调用和传址调用👉点我 今天让我们以汇编语言来了解函数调用的参数
压栈
这一知识点 所用编译器:VS2019 1.什么是栈区? 栈,是一种数据结构。 在
c语言
函数参数
压栈
,函数调用
压栈
浅谈C语言函数调用参数
压栈
的相关问题
想了解浅谈C语言函数调用参数
压栈
的相关问题的相关内容吗,在本文为您仔细讲解函数调用
压栈
的相关知识和一些Code实例,欢迎阅读和指正,我们先划重点:函数调用
压栈
,下面大家一起来学习吧。参数入栈的顺序以前在面试中被人问到这样的问题,函数调用的
时
候,参数入栈的顺序是从左向右,还是从右向左。参数的入栈顺序主要看调用方式,一般来说,__cdecl 和__stdcall 都是参数从右到左入栈。看下面的代码:#...
C++函数调用的
压栈
过程
需要注意的是,栈的管理是由编译器和操作系统来完成的,具体的实现可能有所不同。C++函数调用的
压栈
过程是指在函数调用
时
,将函数的相关信息和局部变量等数据存储在栈(Stack)上的过程。上述示例展示了函数调用的
压栈
过程,包括参数的传递、局部变量的分配和返回地址的保存。在函数调用之前,将下一条指令的地址(函数调用后执行的下一条指令)压入栈中,以便函数执行完后能够返回到正确的位置。函数调用完成后,会按照相反的顺序将栈上的数据出栈,恢复到
调用函数
的状态,并将控制权返回给
调用函数
。函数,按照从右到左的顺序压入栈中。
C/C++函数调用的
压栈
模型
函数调用的
压栈
模型对于我们学习C语言非常重要,最直观的体现在我们后面要学的函数的递归,函数的递归就充分利用的函数的
压栈
模型。 当函数从入口函数main函数开始执行
时
,编译器会将我们操作系统的运行状态,main函数的返回地址、main的参数、main函数中的变量、进行依次
压栈
;当main函数开始调用fa()函数
时
,编译器此
时
会将main函数的运行状态进行
压栈
,再将fa(...
函数
调用函数
的
压栈
1 _cdecl 按从右至左的顺序压参数入栈,由调用者把参数弹出栈。对于“C”函数或者变量,修饰名是在函数名前加下划线。对于“C++”函数,有所不同。如函数void test(void)的修饰名是_test;对于不属于一个类的“C++”全局函数,修饰名是?test@@ZAXXZ。 这是MFC缺省调用约定。由于是调用者负责把参数弹出栈,所以可以给函数定义个数不定的参数,如
C语言
70,020
社区成员
243,264
社区内容
发帖
与我相关
我的任务
C语言
C语言相关问题讨论
复制链接
扫一扫
分享
社区描述
C语言相关问题讨论
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章