个人理解函数返回局部变量

 

代码如下:

#include <cstdio>

	struct node
	{
		int a;
		int b;
		int c;
		int d;
		int f;
		int g;
		int h;
		int i;
	};

	struct node RetStruct()
	{
		struct node stNode;
		stNode.a = 1;
		stNode.b = 2;
		stNode.c = 3;
		stNode.d = 4;
		stNode.f = 5;
		stNode.g = 6;
		stNode.h = 7;
		stNode.i = 8;
		return stNode;
	}
int main()
{

	struct node stRet = RetStruct();
	printf("%d, %d", stRet.a, stRet.b);
	return 0;
}


main反汇编后为:

个人理解函数返回局部变量_第1张图片

从(0041144D ~ 0041145A)中看出,当返回的局部变量无法用寄存器保存时,返回指向局部变量的地址于EAX,并接下复制局部变量于临时变量(0041145A)。

最后把临时变量的数据复制到 stRet 中(0041145C ~ 0041146A)。

看下返回的局部变量可以用寄存器容纳下时

#include <cstdio>

struct node { int a; int b; };

struct node RetStruct() { struct node stNode; stNode.a = 1; stNode.b = 2; return stNode; } int main() {

struct node stRet = RetStruct(); printf("%d, %d", stRet.a, stRet.b); return 0; }


main反汇编后,如下:

个人理解函数返回局部变量_第2张图片

用EAX返回node.a == 1再用 EDX返回node.b == 2 (00411443 ~ 00411449),最后才复制到stRet中(0041144F~0041145E)

总结:

足够用寄存器保存时寄存器保存,不足时,EAX保存临时变量地址返回:

1)先从调用函数开劈1个结构体大小的临时内存,把这个临时结构体地址(设为RetAddress)用EAX而且入栈,以传递给被调用函数RetStruct()中,这个临时结构体保存被调用函数中的要返回的局部结构体的值。

2)被调用函数在返回前把要返回的局部变量结构体的值复制到RetAddress结构体中,然后把RetAddress的地址保存于EAX中,并且被调用函数弹栈返回

3)被调用函数返回后,立即复制RetAddress结构体的值于另一个结构体的地址中,设为Address(注:这个地址不是RetAddress)

4)再次复制Adress的值保存于MAIN的局部变量stRet中


到此,执行struct node stRet = RetStruct();这条语句结束,这个语句执行,总共进行了3次结构体值的复制:RetStruct()函数内部1次,main()内部2次

你可能感兴趣的:(个人理解函数返回局部变量)