函数参数压栈方式为什么是从右到左的?

marginyl 2014-09-10 10:14:49
加精
大家都清楚函数参数压栈顺序是从右往左的,但是参加百度面试的时候,面试官问了我:为什么要是从右往左的?我答不出来,这其中的原因我还是摸不着头脑,请懂的大牛指教指教!
...全文
8849 37 打赏 收藏 转发到动态 举报
写回复
用AI写文章
37 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2016-05-18
  • 打赏
  • 举报
回复
不要迷信书、考题、老师、回帖; 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实! 有人说一套做一套,你相信他说的还是相信他做的? 其实严格来说这个世界上古往今来所有人都是说一套做一套,不是吗? 不要写连自己也预测不了结果的代码!
赵4老师 2016-05-18
  • 打赏
  • 举报
回复
ypzhong 2016-05-18
  • 打赏
  • 举报
回复
为了支持边长参数,其他原因应该没有了。
天才2012 2016-05-18
  • 打赏
  • 举报
回复
最终目的还是为了方便编译器。编译器处理为汇编时,栈帧的处理,参数的访问,一旦动态参数时,从左到右,可以想象汇编代码根本表述不了
lm_whales 2015-10-12
  • 打赏
  • 举报
回复
这是C调用约定的样子
是C刚开发出来时候的样子

第一个版本的C就是自右向左压栈的
因为此时 C的函数,
还是可以有不确定个参数的
函数原型,还没有受到重视
例如,迄今为止
main 函数,还可以至少有两种形式
int main(){
return 0;
};
int main(int argc,char *argv[]){
return 0;
}
对于这种不能确定参数个数和类型的函数,C调用约定,就很自然了

如今,像 printf 还需要这种调用约定来支持

要知道C没有所谓的内部函数
因此,不能像Fortran 那样
依赖内部函数,实现输入输出
所以需要这种不定参数的函数。

qq_31942159 2015-10-12
  • 打赏
  • 举报
回复
看不懂,一个个好牛
  • 打赏
  • 举报
回复
这只是cdecl调用约定而已,也可以不这么传参,pascal调用约定从左到右传参,win64 ABI的调用约定左面4个参数优先使用寄存器传递,也不是从右开始的。
czg2020czg 2015-10-12
  • 打赏
  • 举报
回复
顶楼主,顶楼主
xuzuning 2015-10-12
  • 打赏
  • 举报
回复
凡事并不一定要有理由的,一开始这么做了,以后也就习惯俗成了
C是 从右往左
Pascal 就是 从左往右 的
Downey_W 2015-10-11
  • 打赏
  • 举报
回复 1
因为C++支持可变长函数参数。正是这个原 因使得C语言函数参数入栈顺序为从右至左。具体原因为:C方式参数入栈顺序(从右至左)的好处就是可以动态变化参数个数。C 程序栈底为高地址,栈顶为低地址。函数最左边确定的参数在栈上的位置必须是确定的,否则意味着已经确定的参数是 不能定位和找到的,这样是无法保证函数正确执行的。衡量参数在栈上的位置,就是离开确切的 函数调用点(call f)有多远。已经确定的参数,它在栈上的位置,不应该依 赖参数的具体数量,因为参数的数量是未知的!

所以只有确定的参数最后入栈才能保证它在栈中的位置是确定的。
b_duan 2015-10-10
  • 打赏
  • 举报
回复
学习了,感觉可变参数的分析靠谱。
gotopause 2015-10-10
  • 打赏
  • 举报
回复
好高深莫测啊,估计我这辈子都学不会C了
xiaoxiangqing 2015-10-10
  • 打赏
  • 举报
回复
应该是有理由的,不然也不会这样
cattpon 2015-10-10
  • 打赏
  • 举报
回复
引用 2 楼 brookmill 的回复:
据说是为了支持可变长参数
这个回答好牛逼~ 感觉得上知乎~
bluewanderer 2015-10-10
  • 打赏
  • 举报
回复
大多数环境栈都是从高地址往低地址用的,如果从左压,不定参数往后取在内存里就成往前走了。 而栈从高往低用是很久很久以前为了尽量不和别的内存使用打架,而复杂指令集CPU压栈出栈逻辑是写死的,所以虽然现在没这个必要了,但是为了兼容还保留了这个逻辑。
fefe82 2015-10-10
  • 打赏
  • 举报
回复
引用 24 楼 gotopause 的回复:
好高深莫测啊,估计我这辈子都学不会C了
这事跟 C 其实没多大关系 ...
nj_dobetter 2015-10-10
  • 打赏
  • 举报
回复
从左向右和从右向左两种顺序都有可能。 从右向左压栈是为了支持可变参数的函数调用。
赵4老师 2015-10-09
  • 打赏
  • 举报
回复
理解讨论之前请先学会如何观察! 计算机组成原理→DOS命令→汇编语言→C语言(不包括C++)、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言(包括C++)、架构…… 对学习编程者的忠告: 多用小脑和手,少用大脑、眼睛和嘴,会更快地学会编程! 眼过千遍不如手过一遍! 书看千行不如手敲一行! 手敲千行不如单步一行! 单步源代码千行不如单步Debug版对应汇编一行! 单步Debug版对应汇编千行不如单步Release版对应汇编一行! VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。 对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。 (Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)
别打名名 2015-10-09
  • 打赏
  • 举报
回复 1
找了很多资料,都没怎么搞懂,最后整理了下,我还算是说的清楚了:http://blog.csdn.net/FreeApe/article/details/48999063
mail_xuan 2015-07-06
  • 打赏
  • 举报
回复
从右向左压栈,不是规定,也不是因为栈先进后出的特性。在《c和指针》中已经说明了从右向左压栈的原因,这样可以保证生成汇编语言时这些参数相对于BP指向的栈位置的偏移量是固定的,因为程序员有时为函数传递的参数会或多或或少,如果从左向右压栈,则从BP指向的位置到参数的偏移量就会根据用户传入的参数数量而发生改变,这时编译器的识别难度就会大大增加,因此才会从右向左压栈。其实从我们平时的程序中就可以发现,如果我们的C程序函数参数比较少的话,传进去的前几个参数是可以正常接收的;如果参数传递地多的话,多余的参数也会丢弃,就是这个原理,你也会发现,从右向左可以非常好地降低编译器的操作难度。建议阅读C语言三剑客:《c和指针》《C专家编程》《C陷阱和缺陷》
加载更多回复(17)

65,060

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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