这篇文章是从《程序员的自我修养》中摘录的一小点。我个人认为很不错,就总结了一下。一般情况下,我们都知道返回值是通过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!
整个流程如图所示。
同样可以用伪代码表示