x86-64架构下函数调用栈与32位下的不同之处

本文探讨了x86-64架构下函数调用栈的特点,指出在未优化的gcc 5.4.0中,参数首先从右向左存入寄存器,然后在函数内部从左向右入栈。当参数数量超过寄存器容量时,剩余参数依然遵循从右向左入栈的规则。若函数内部不调用其他函数且参数占用空间小于128字节,参数则存放在栈顶之外,栈顶不增长。
摘要由CSDN通过智能技术生成


本文目的

 
  之前,我本想观察函数调用时,栈的细节。顺便验证一下,口口相传的,C/C++从右向左入栈。详情参考之前的文章:C++函数调用栈细节(gdb调试)结果发现了些出乎意料的情况。
在x86-64 gcc 5.4.0 没有优化选项时
代码:

1 #include<stdio.h>
  2 
  3 class A {
   
  4     public:
  5         int f;
  6         int s;
  7 };
  8 
  9 int sum(int l,int r)
 10 {
   
 11     int res =0;
 12     res = l+r;
 13     return res;
 14 }
 15 int main ()
 16 {
   
 17     A a;
 18     a.f = 0x55;
 19     a.s = 0x66;
 20     int res = sum(a.f,a.s);
 21     printf("sum: %d",res);
 22     return 0;
 23 }

出现了:

  1. 调用函数前参数没有入栈,而是按照从右向左的顺序存放在了寄存器。
  2. 进入调用函数后,参数从寄存器存放进了栈中,但是按照从左到右的顺序。
  3. 进入调用函数后rsp栈顶指针没有增长,第2条里的参数存放在了栈顶之外。

以上三条可以在C++函数调用栈细节(gdb调试)中看到调试的具体情况。


x86-64下打印参数地址判断参数入栈顺序的做法不合理

 
  之前看过很多判断参数入栈顺序,通过打印参数的地址,根据右边参数为高地址,左边参数为低地址,就得出参数是从右向左入栈。但是在x86-64下,这样行不通。

  	1 #include<stdio.h>
    2 
    3 void foo(int x, int y)
    4 {
   
	5         printf("x = %d at [%X]\n", x, &x);
	6         printf("y = %d at [%X]\n", y, &y);
    7 }
    8 
    9 int main ()                                                               
   10 {
   
   11     foo(100,300);
   12     return 0;
   13 }

不添加优化选项编译
在这里插入图片描述
结果:
在这里插入图片描述
左边参数地址高于右边参数地址。

难道这就说明了 参数从左向右入栈的?有些偏颇。

情况1:函数调用参数从右向左存放到寄存器,又从左到右存放到栈

  

0000000000400526 <foo>:
  400526:	55                   	push   %rbp
  400527:	48 89 e5             	mov    %rsp,%rbp
  40052a:	48 83 ec 10          	sub    $0x10,%rsp 栈顶有增长
  40052e:	89 7d fc             	mov    %edi,-0x4(%rbp) edi即左边参数100,先存放在高地址(靠近栈底)
  400531:	89 75 f8             	mov    %esi,-0x8(%rbp) esi即右边参数300,后存放在低地址
  400534:	8b 45 fc             	mov    -0x4(%rbp),%eax
  400537:	48 8d 55 fc          	lea    -0x4(
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值