函数调用返回值传递的三种情形

这篇文章是从《程序员的自我修养》中摘录的一小点。我个人认为很不错,就总结了一下。一般情况下,我们都知道返回值是通过eax这个寄存器返回的。但是,eax本身只能存储4个字节的数据,对于那些返回值大于4个字节的数据应该怎么返回呢?下面我们把它分为3中情况:
第一种情形:小于四个字节。解决之道:直接放到eax中返回。
第二种情形:大于四个字节,小于8个字节。解决之道:采用eax和edx联合方式进行。eax存储返回值的低4个字节,edx存储返回值的高四个字节。
第三种情形:大于8个字节。这就是本篇要研究的内容。


以下面的代码为例,

从上述代码可知,return_test()返回的一个128字节的数据结构,怎么办呢?


接下来,我们将从头到尾理一下思路:
1,首先我们在main函数的栈帧上开辟一片空间,我们这里假设开始时main栈帧的地址为Old_ebp,变量n存放在Old_ebp - 88h的地址处。而【Old_ebp-1D0h,Old_ebp - 88h】这段空间地址作为临时空间temp,接收从被调用函数返回的数据。
2,将temp对象的地址,也就是Old_ebp-1D0h作为隐藏参数传递给return_test()函数。
3,在return_test()函数的栈帧上,我们为局部变量b创建了128字节的空间,并对它进行了赋值。然后将这些数据拷贝给temp对象。怎么拷贝的呢?因为我们的temp对象的地址为Old_ebp-1D0h,它是作为隐含参数传递进来的,因此,通过edp+8直接就可以找到temp对象的地址了。然后,将temp对象的地址用eax传出。为什么要返回temp对象这个地址呢?因为return_test()返回后,它的栈帧也同样撤销了,所以到main函数后,我们需要temp对象的地址来把它里面的内容拷贝到变量n处(Old_ebp - 88h)。
4,return_test()返回后,main函数将eax指向的temp对象中的内容拷贝给n,OK!


整个流程如图所示。


同样可以用伪代码表示

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值