您的位置:首页 > 其它

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

2011-11-10 03:27 246 查看
代码如下:

#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反汇编后为:



从(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反汇编后,如下:



用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次

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: